java暂停线程

暂停线程

本节介绍两个被废弃的用于线程暂停和恢复的方法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();
}

也会可能产生不同步的问题。

posted @ 2019-06-01 19:08  落音  阅读(224)  评论(0编辑  收藏  举报