【Java多線程學習筆記】suspend及resume方法的缺點——獨佔

“在使用suspend與resume方法時,如果使用不當,極易造成公共的同步對象獨佔,使得其他線程無法訪問公共同步對象”

 

【獨佔原因&代碼分析】

1、在同步方法printString() 中線程a被暫停,鎖無法釋放,其他線程無法訪問printString() 

package suspend_resume_deal_lock;

/**
 * @author chengsw
 * @create 2019-06-30 15:50
 */
public class SynchronizedObject {

    synchronized public void printString() {
        System.out.println("begin");
        if (Thread.currentThread().getName().equals("a")) {
            System.out.println("a線程永遠suspend");
            Thread.currentThread().suspend();
        }
        System.out.println("end");
    }
}
package suspend_resume_deal_lock;

/**
 * @author chengsw
 * @create 2019-06-30 15:59
 */
public class Run {

    public static void main(String[] args) {
        try {
            final SynchronizedObject so = new SynchronizedObject();
            Thread th1 = new Thread() {
                @Override
                public void run() {
                    so.printString();
                }
            };
            th1.setName("a");
            th1.start();
            Thread.sleep(2000);
            Thread th2 = new Thread() {
                @Override
                public void run() {
                    System.out.println("thread2線程啓動了,但是不能進入println方法,因爲線程已經被a鎖定且暫停");
                    System.out.println("因爲printString()方法被a線程鎖定並且永遠suspend暫停了!");
                    so.printString();
                }
            };
            th2.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

運行結果

2、println()造成的鎖不能釋放

package suspend_resume_LockStop;

/**
 * @author chengsw
 * @create 2019-06-30 16:12
 */
public class MyThread extends Thread {

    private long i = 0;

    @Override
    public void run() {
        while(true) {
            i++;
            System.out.println(i);
        }
    }
}
package suspend_resume_LockStop;

/**
 * @author chengsw
 * @create 2019-06-30 16:18
 */
public class Run {

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

運行結果:

並沒有打印main end~~

由上面源碼可知,當程序運行到println()內部暫停線程時,同步鎖無法釋放。

當前PrintStream對象的println()方法在同步代碼塊內暫停,則println()的鎖一直無法釋放,因此一直打印數據,但無法執行main方法中的println("main end~~")

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