JAVA多線程編程——1.8 線程暫停

1.8 線程暫停

1.8.2 suspend()方法的獨佔行爲

可以用Thread對象的suspend()以及resume()方法,但是這兩種方法是獨佔同步對象的。

public class Thread_182_1 {
static class SynchronizedObject{
    synchronized public void printSome(){
        System.out.println("begin-->");
        if(Thread.currentThread().getName().equals("a")){
            System.out.println("a線程被suspend了!");
            Thread.currentThread().suspend();
        }
        System.out.println("end");
    }
}

public static void main(String[] args) {
    try{
        final SynchronizedObject object1 = new SynchronizedObject();
        Thread thread1 = new Thread(){
            public void run(){
                object1.printSome();
            }
        };
        thread1.setName("a");
        thread1.start();
        Thread.sleep(1000);
        Thread thread2 = new Thread(){
            public void run(){
                System.out.println("thread2啓動了,但進入不了printSome()方法,因爲被線程a鎖定並且a被掛起了");
                object1.printSome();//卡在了這裏
                System.out.println("thread2的printSome啓動了");
            }
        };
        thread2.start();
    }catch(InterruptedException e){
        e.printStackTrace();
    }
}
}

輸出爲:
begin–>
a線程被suspend了!
thread2啓動了,但進入不了printSome()方法,因爲被線程a鎖定並且a被掛起了
因爲前面的printSome()是同步方法,線程a 沒有釋放該鎖,所以卡在了註釋行

public class Thread_182_2 {
   static class MyThread extends Thread{
    private long i=0;
    public void run(){
        while(true){
            i++;
        }
    }
}

public static void main(String[] args) {
    try{
        MyThread thread = new MyThread();
        thread.start();
        Thread.sleep(1000);
        thread.suspend();
        System.out.println("main end");
    }catch(InterruptedException e){
        e.printStackTrace();
    }
}

}

輸出爲:
main end

其中thread被掛起。

但是如果把MyThread改爲:

static class MyThread extends Thread{
    private long i=0;
    public void run(){
    while(true){
        i++;
        System.out.println(i);
    }
}
}

則輸出爲:
115332
115333
115334
115335
115336
也是因爲suspend()不釋放鎖,而println() 方法的源碼中是同步代碼塊
public void println(long x) {
synchronized (this) {
print(x);
newLine();
}
}

最後要說的,suspend()方法已經過時了。

1.8.3 suspend與resume方法的缺點——不同步

一般是因爲suspend()用法出現錯誤,錯誤的掛起導致不同步。

public class Thread_183 {
static class MyObject{
    private String username ="1";
    private String password ="11";
    public void setValue(String u,String p){
        this.username = u;
        if(Thread.currentThread().getName().equals("a")){
            System.out.println("停止a線程!");
            Thread.currentThread().suspend();
        }
        this.password=p;
    }

    public void printInfo(){
        System.out.println(username+"--"+password);
    }
}

public static void main(String[] args) throws InterruptedException {
    final MyObject myObject = new MyObject();
    Thread thread1 = new Thread(){
        public void run(){
                myObject.setValue("a","aa");
        };
    };
    thread1.setName("a");
    thread1.start();
    Thread.sleep(500);
    Thread thread2 = new Thread(){
        public void run(){
            myObject.printInfo();
        }
    };
    thread2.start();
}

}

輸出爲:
停止a線程!
a–11
因爲前面的方法中在完成設置username後進行了判斷,如果是線程a就掛起,然後後面的this.password =p就不能執行了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章