《Java多线程编程核心技术(第2版)》 —1.12.2 suspend()方法与resume()方法的缺点—独占
1.12.2 suspend()方法与resume()方法的缺点—独占
如果suspend()方法与resume()方法使用不当,极易造成公共同步对象被独占,其他线程无法访问公共同步对象的结果。
创建suspend_resume_deal_lock项目,文件SynchronizedObject.java代码如下:
package testpackage;
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");
}
}
文件Run.java代码如下:
package test.run;
import testpackage.SynchronizedObject;
public class Run {
public static void main(String[] args) {
try {
final SynchronizedObject object = new SynchronizedObject();
Thread thread1 = new Thread() {
@Override
public void run() {
object.printString();
}
};
thread1.setName("a");
thread1.start();
Thread.sleep(1000);
Thread thread2 = new Thread() {
@Override
public void run() {
System.out.println("thread2启动了,但进入不了printString()方法!只打印1个begin");
System.out.println("因为printString()方法被a线程锁定并且永远suspend暂停了!");
object.printString();
}
};
thread2.start();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
程序运行结果如图1-55所示。
另外一种独占锁的情况也需要格外注意,稍有不注意,就会掉进“坑”里。创建测试用的项目suspend_resume_LockStop,类MyThread.java代码如下:
图1-55 独占并锁死printString()方法
package mythread;
public class MyThread extends Thread {
private long i = 0;
@Override
public void run() {
while(true) {
i++;
}
}
}
类Run.java代码如下:
package test.run;
import mythread.MyThread;
public class Run {
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();
}
}
}
程序运行结果如图1-56所示。
进程状态在控制台中呈红色按钮显示,说明进程并未销毁。虽然main线程销毁了,但是MyThread呈暂停状态,所以进程不会销毁。
但如果将线程类MyThread.java更改如下:
package mythread;
public class MyThread extends Thread {
private long i = 0;
@Override
public void run() {
while (true) {
i++;
System.out.println(i);
}
}
}
再次运行程序,控制台不输出main end,如图1-57所示。
图1-57 不输出main end信息
出现这种情况的原因是当程序运行到System.out.println(i)方法内部停止时,同步锁是不释放的,println()方法源代码如图1-58所示。
图1-58 锁不释放
当前PrintStream对象的println()方法一直呈“暂停”状态,并且“锁未释放”,而main()方法中的代码“System.out.println("main end!");”也需要这把锁,main线程并未销毁,造成迟迟不能输出main end。
虽然suspend()方法是过期作废的方法,但研究其过期作废的原因是很有必要的。
- 点赞
- 收藏
- 关注作者
评论(0)