JDK1.0定义了stop和suspend方法:
从JDK1.2开始,这两个方法都被弃用了.stop天生就不安全,而经验告诉我们呢suspend方法会经常导致死锁。
stop这个方法将终止所有未结束的方法,包括run方法。当一个线程使用 stop() 暴力停止时候,他会立即释放所有他锁住对象上的锁。这会导致对象处于不一致的状态(不同步)。假如一个方法在将钱从一个账户转移到另一个账户的过程中,在取款之后存款之前就停止了。那么现在银行对象就被破坏了。因为锁已经被释放了。当线程想终止另一个线程的时候,它无法知道何时调用stop是安全的,何时会导致对象被破坏。所以这个方法被弃用了。你应该中断一个线程而不是停止他。
suspend不会破坏对象。但是,如果你用一个suspend挂起一个有锁的线程,那么在锁恢复之前将不会被释放。如果调用suspend的方法线程试图取得相同的锁,程序就会死锁。
那么在程序中该怎么样使用线程呢?建议如下:
(1)最好不要使用Lock/Condition也不使用synchronized关键字。在很多情况下你可以使用java.util.concurrent包中的一种机制,它会为你处理所有的加锁。例如阻塞同步队列。
(2)如果synchronized关键字在程序中可以工作,那么就尽量使用它,这样可以减少代码数量和出错的几率。
(3)只有在非常需要Lock/Condition结构特性的时候才使用他们。
上面文字参考:http://blog.sina.com.cn/s/blog_68564f2f0100iyfz.html
关于 suspend 会产生死锁这里举一个例子
1、先注释掉第9行
运行结果如下
thread 线程暂停后,然后 main 线程得以执行,输出 main end
2、现在我们把注释去掉,让它打印 System.out.println(i);
效果图如下
thread 线程暂停后,始终没有输出 main end,很可能是发生了死锁。
我们查看 println() 的源码发现,确实有锁
然后我们知道,当执行到 thread.suspend(); 的时候,thread 线程被暂停,却没有释放锁,其他线程都不能访问资源。而此时,程序运行到了 println() 方法内部,导致 println() 方法一直处于暂停状态,并且“锁未被释放”而 main 方法里的 System.out.println("main end"); 也迟迟不能打印。
如何安全地暂停一个线程
我们可以试图用 volatile 关键字修饰一个布尔类型的标志变量,判断标志来判断是否退出 run
从JDK1.2开始,这两个方法都被弃用了.stop天生就不安全,而经验告诉我们呢suspend方法会经常导致死锁。
stop这个方法将终止所有未结束的方法,包括run方法。当一个线程使用 stop() 暴力停止时候,他会立即释放所有他锁住对象上的锁。这会导致对象处于不一致的状态(不同步)。假如一个方法在将钱从一个账户转移到另一个账户的过程中,在取款之后存款之前就停止了。那么现在银行对象就被破坏了。因为锁已经被释放了。当线程想终止另一个线程的时候,它无法知道何时调用stop是安全的,何时会导致对象被破坏。所以这个方法被弃用了。你应该中断一个线程而不是停止他。
suspend不会破坏对象。但是,如果你用一个suspend挂起一个有锁的线程,那么在锁恢复之前将不会被释放。如果调用suspend的方法线程试图取得相同的锁,程序就会死锁。
那么在程序中该怎么样使用线程呢?建议如下:
(1)最好不要使用Lock/Condition也不使用synchronized关键字。在很多情况下你可以使用java.util.concurrent包中的一种机制,它会为你处理所有的加锁。例如阻塞同步队列。
(2)如果synchronized关键字在程序中可以工作,那么就尽量使用它,这样可以减少代码数量和出错的几率。
(3)只有在非常需要Lock/Condition结构特性的时候才使用他们。
上面文字参考:http://blog.sina.com.cn/s/blog_68564f2f0100iyfz.html
关于 suspend 会产生死锁这里举一个例子
1、先注释掉第9行
- class MyRunnable implements Runnable {
- public static int i = 0;
- @Override
- public void run() {
- while (true) {
- i++;
- // System.out.println(i);
- }
- }
- }
- public class Demo {
- public static void main(String args[]) throws InterruptedException {
- MyRunnable myRunnable = new MyRunnable();
- Thread thread = new Thread(myRunnable);
- thread.start();
- Thread.sleep(1000);
- thread.suspend();
- System.out.println("main end");
- }
- }
运行结果如下
thread 线程暂停后,然后 main 线程得以执行,输出 main end
2、现在我们把注释去掉,让它打印 System.out.println(i);
效果图如下
thread 线程暂停后,始终没有输出 main end,很可能是发生了死锁。
我们查看 println() 的源码发现,确实有锁
然后我们知道,当执行到 thread.suspend(); 的时候,thread 线程被暂停,却没有释放锁,其他线程都不能访问资源。而此时,程序运行到了 println() 方法内部,导致 println() 方法一直处于暂停状态,并且“锁未被释放”而 main 方法里的 System.out.println("main end"); 也迟迟不能打印。
如何安全地暂停一个线程
我们可以试图用 volatile 关键字修饰一个布尔类型的标志变量,判断标志来判断是否退出 run
- class MyRunnable implements Runnable {
- public static int i = 0;
- static volatile boolean stop = false;
- @Override
- public void run() {
- while (!stop) {
- i++;
- System.out.println(i);
- }
- }
- public void stop() {
- stop = true;
- }
- }
- public class Demo {
- public static void main(String args[]) throws InterruptedException {
- MyRunnable myRunnable = new MyRunnable();
- Thread thread = new Thread(myRunnable);
- thread.start();
- Thread.sleep(1000);
- myRunnable.stop();
- System.out.println("main end");
- }
- }
您可以选择一种方式赞助本站
支付宝扫一扫赞助
微信钱包扫描赞助
赏