[Android] Thread#3 WorkerThread的suspend與resume

雖然在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()。