zoukankan      html  css  js  c++  java
  • java中的wait(),notify(),notifyAll(),synchronized方法

    wait(),notify(),notifyAll()三个方法不是Thread的方法,而是Object的方法。意味着所有对象都有这三个方法,因为每个对象都有锁,所以自然也都有操作锁的方法了。这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。

    java文档的解释

    wait导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行.

      notify唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。直到当前的线程放弃此对象上的锁定,才能继续执行被唤醒的线程。此方法只应由作为此对象监视器的所有者的线程来调用.

      "当前的线程必须拥有此对象监视器"与"此方法只应由作为此对象监视器的所有者的线程来调用"说明wait方法与notify方法必须在同步块内执行,即synchronized(obj之内).

      调用对像wait方法后,当前线程释放对像锁,进入等待状态.直到其他线程(也只能是其他线程)通过notify 方法,或 notifyAll.该线程重新获得对像锁.

    例子代码:

    说明:线程运行3秒后调用wait等待,6秒后主线程调用notify唤醒等待线程。

     1 /**
     2  * Created on 2016/1/31.
     3  */
     4 public class MyThread implements Runnable {
     5     private Object flag;
     6     private String threadName;
     7 
     8     public MyThread(Object flag,String threadName) {
     9         this.flag = flag;
    10         this.threadName = threadName;
    11     }
    12 
    13     @Override
    14     public void run(){
    15         try{
    16             for(int i = 0; i < 10;i++){
    17                 if(i == 3){
    18                     synchronized (this.flag){
    19                         System.out.println("3秒后线程调用wait睡眠");
    20                         this.flag.wait();
    21                     }
    22                 }
    23                 System.out.println(this.threadName + " " + i);
    24                 Thread.sleep(1000);
    25             }
    26         } catch(InterruptedException e){
    27             e.printStackTrace();
    28         }
    29 
    30     }
    31 }

    main方法:

     1 import java.io.IOException;
     2 
     3 /**
     4  * Created  on 2016/1/31.
     5  */
     6 public class TestMain {
     7     public static void main(String[] args) {
     8         Object object = new Object();
     9         MyThread myThread1 = new MyThread(object,"thread1");
    10 //        MyThread myThread2 = new MyThread(object,"thread2");
    11         Thread test1 = new Thread(myThread1);
    12         test1.start();
    13 
    14 //        Thread test2 = new Thread(myThread1);
    15 //        test2.start();
    16 
    17         try{
    18             Thread.sleep(6000);
    19             System.out.println("6秒后唤醒线程");
    20             synchronized (object){
    21                 object.notify();
    22             }
    23             System.in.read();
    24         } catch(InterruptedException e){
    25             e.printStackTrace();
    26         } catch(IOException e){
    27             e.printStackTrace();
    28         }
    29 
    30     }
    31 }

    结果:

    测试notifyAll(MyThread代码不变)

    main方法代码:

     1 import java.io.IOException;
     2 
     3 /**
     4  * Created on 2016/1/31.
     5  */
     6 public class TestMain {
     7     public static void main(String[] args) {
     8         Object object = new Object();
     9         MyThread myThread1 = new MyThread(object,"thread1");
    10         MyThread myThread2 = new MyThread(object,"thread2");
    11         Thread test1 = new Thread(myThread1);
    12         test1.start();
    13 
    14         Thread test2 = new Thread(myThread2);
    15         test2.start();
    16 
    17         try{
    18             Thread.sleep(6000);
    19             System.out.println("6秒后唤醒线程");
    20             synchronized (object){
    21                 object.notifyAll();
    22             }
    23             System.in.read();
    24         } catch(InterruptedException e){
    25             e.printStackTrace();
    26         } catch(IOException e){
    27             e.printStackTrace();
    28         }
    29 
    30     }
    31 }

    结果截图:

  • 相关阅读:
    【python】Python 资源大全中文版
    获取最新chromedriver.exe的方法,并查阅最新的chromedriver.exe支持到什么chrome版本
    appium 重新启动apk
    git 命令操作
    [转]IDEA 出现编译错误 Multi-catches are not supported a this language level 解决方法
    jmeter压测前清理内存
    清理kafka zookeeper
    windows 自动移动maven jar包到jmeter 文件夹下面
    jmeter 压测duobbo接口,施压客户端自己把自己压死了
    kafak manager + zookeeper + kafka 消费队列快速清除
  • 原文地址:https://www.cnblogs.com/maxiaofang/p/5173608.html
Copyright © 2011-2022 走看看