赞
踩
暂停线程
本节介绍两个被废弃的用于线程暂停和恢复的方法suspend()、resume()。主要探究废弃原因,强调线程的安全性。主要有两个原因
原因1:
suspend()、resume()使用不当,极易造成对公共的同步对象的独占,使其他线程无法访问同步对象
例如:
package foreverly.cn.chapter1;
public class SynchronizedObject {
synchronized public void printString() {
System.out.println("printString begin");
if (Thread.currentThread().getName().equals("a")) {
System.out.println("a线程永远suspend了");
Thread.currentThread().suspend();
}
System.out.println("end");
}
}
package foreverly.cn.chapter1;
import foreverly.cn.chapter1.SynchronizedObject;
public class Run {
public static void main(String[] args) {
try {
final SynchronizedObject object = new SynchronizedObject();
//使用匿名类的方式创建thread1
// Thread thread1 = new Thread() {
// @Override
// public void run() {
// object.printString();
// }
// () ->{
// object.printString();
// }
// };
//使用lambda表达式创建thread1
Thread thread1 =new Thread( () ->{
object.printString();
});
thread1.setName("a");
thread1.start();
Thread.sleep(1000);
// thread1.resume()
Thread thread2 = new Thread() {
@Override
public void run() {
System.out.println("能打印这句话,说明thread2 启动了,但进不了printString()方法,只能打印出一个printString begin。"
+ "原因是printString()方法被suspend暂停了");
object.printString();
//下面的语句执行不了,因为printString()是 synchronized方法,当一个线程使用时其余线程必须等待;
//当thread1执行printString()时被暂停,但thread1任掌握着printString()方法,thread2就必须
//等待,所以下面的语句执行不了。
System.out.println("这里的就输出不了,因为object.printString();已经暂停了thread2");
}
};
thread2.start();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
输出:
printString begin
a线程永远suspend了
能打印这句话,说明thread2 启动了,但进不了printString()方法,只能打印出一个printString begin。原因是printString()方法被suspend暂停了
原因2:
容易出现因为线程的暂停而导致数据不同步的情况。
这个有点类似于stop(),
例如:
线程a负责更新用户名和密码,run方法时同步的(synchronized 声明),但是当线程a更新完用户名且未更新密码,此时CPU切换至线程b执行。线程b通过a.suspend()暂停了线程a,就会出现密码不同步的现象。
比较有意思的是我们常用的println方法,它的源码是
synchronized (this) {
print(x);
newLine();
}
也会可能产生不同步的问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。