雖然在JAVA中,提供了Thread的suspend()與resume()的語法,但可以看到被槓了一條線且無法使用,為何不能使用與不建議使用~可以GOOGLE大神尋找答案! 此篇文章提供了別種方法來讓Thread suspend與resume,使用了wait()、notify()、以及synchronized()來解決!
以下建立一個testThread為繼承Thread的class,可以看到在testThread內除了run()函數外,另外加了 Tsuspend()與Tresume()兩個函數,以及建立一個判別用的 suspend_flag bool,以下將個別說明。
class testThread extends Thread{
boolean suspend_flag=false;
@Override
public void run(){
int a=0;
while(true){
System.out.println("a"+ (++a));
try {
Thread.sleep(200);
synchronized (this){
while (suspend_flag){
wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
void Tsuspend(){
suspend_flag = true;
}
synchronized void Tresume(){
suspend_flag = false;
notify();
}
}
在此例子當中,建立WorkerThread的方法與一般建立的WorkerThread的方式並無太大差別,只添加了Tsuspend()與Tresume()兩個method來讓Thread達到暫停與繼續的功能。
在run()函數當中,建立一個while(true)迴圈,不斷的打印出a+num...,並與下一次的打印之間delay 200ms,可以發現在delay後面加了 sysnchronized(),Lock此Thread後,便能使用wait() function。
public void run(){
int a=0;
while(true){
System.out.println("a"+ (++a));
try {
Thread.sleep(200);
synchronized (this){ //當一個方法加上關鍵字synchronized 聲明後, 就可以讓一個線程操作這個方法.
// " 讓一個線程操作 "並不是說只能讓一個特定線程操作而已, 而是指同一時間
// 只能讓一個線程執行或存取. 這種現程稱為 synchronized 方法, 又稱同步方法
while (suspend_flag){
wait();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
很明顯地,下面的 method 主要功能是將flag改變為true,使run()中的while(suspend_flag)啟動,並使用wait(),使此Thread達到暫停的效果。
void Tsuspend(){
suspend_flag = true;
}
而Tresume()的功能便是將flag改變為false,使while(suspend_flag)為false離開迴圈,並使用notify()喚醒Thread,需要注意的是此 method前面有加 synchronized關鍵字,這是因為使用了notify(),因此必須先Lock Thread。
synchronized void Tresume(){
suspend_flag = false;
notify();
}
添加了以上兩個method後,便能在其他地方隨意地暫停與繼續此Thread的功能了,例如首先建立此方法
testThread tt=new testThread();
接著便能在Button當中調用函數使Thread暫停與繼續
suspendbtn.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
tt.Tsuspend();
}
});
resumebtn.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
tt.Tresume();
}
});
另外也可以直接在Button中直接調用tt.notify(),而不需再透過Thread內的 Tresume(),方法如下
resumebtn.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View v) {
synchronized (tt){
tt.suspend_flag=false;
tt.notify();
}
}
});
需要注意的是,必須使用synchornized(tt) Lock住 tt Thread,才能使用 tt.notify()。