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