“在使用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~~")