首页 > 代码库 > java 线程交互之wait/notify

java 线程交互之wait/notify

众所周知java支持多线程,有多线程就必然会存在多线程的交互,交互方式有多种,比如通过共享数据,或者通过提供的锁信号量等等,这里通过用wait以及notify实现线程交互。

 

要用好线程的wait和notify就要首先了解一下线程的状态,线程的状态大致可以划分为一下几种,创建->就绪->运行->阻塞->销毁

一个线程通过new 到调用start完成了创建到就绪,这个之后就是等待cpu分配资源运行,阻塞的状态是发生在线程运行状态之后,发生线程阻塞的情况有很多种,这里简单的列举一下

                             1>锁阻塞

                             2>调用wait阻塞

                             3>调用join阻塞

                             4>调用sleep阻塞

 

当然线程也可以从运行状态返回到就绪状态,这个是通过调用Thread类的yeild方法实现的,这里简单说明一下,wait以及notify和notifyall是在超父类Object中提供的,也就是说属于类的

,而sleep/join/yeild是Thread这个类提供的,也即是属于线程的

从上可知,wait以及notify是只能用在对象锁上,不能和共享锁一起使用即只能和synchroized这个关键之一起使用,也就是说用wait和notify之前,必须先获得对象的锁,当调用wait的时候,

线程被放入对象监视器的等待队列里面,而且会释放锁,等待其他线程调用notify从锁对象监视器的等待队列里,取得一个线程执行,记着,synchronized是对象锁,就是说她要锁整个对象。

 

通过以上我们大致了解了,wait和notify的知识点,下面请看例子,简单的生产者消费者的例子

 1 public class Test { 2  3     private static List<Integer> queue = new ArrayList<>(); 4      5      6     /** 7      * 生产者 8      * @param n     void 9      *     10      */ 11     public synchronized void producer(int n){12         System.out.println("insert data "+n);13         queue.add(n);14         15         if(queue.size()==1)16             this.notify();17     }18     19     /**20      * 消费者21      * @return     int22      *     23      */ 24     public synchronized int consumer(){25             try {26                 if(queue.isEmpty())27                     this.wait();28             } catch (InterruptedException e) {29                 e.printStackTrace();30             }31         int result = queue.get(0);32         queue.remove(0);33         return result;34     }35     36     public static void main(String[] args) {37         final Test test = new Test();38         39         Thread thread1 = new Thread(new Runnable() {//生产线程40             41             @Override42             public void run() {43                 Random random = new Random();44                 try {45                     while(true){46                         test.producer(random.nextInt(1000));47                         Thread.sleep(2000);48                     }49                 } catch (InterruptedException e) {50                     e.printStackTrace();51                 }52             }53         });54         55         Thread thread2 = new Thread(new Runnable() {//消费线程56             57             @Override58             public void run() {59                 try {60                     while(true){61                         System.out.println("select data is "+test.consumer());62                         Thread.sleep(1000);63                     }64                 } catch (InterruptedException e) {65                     e.printStackTrace();66                 }67             }68         });69         70         thread1.start();71         thread2.start();72     }73 }

 

以上是个人的理解,如有误的地方,欢迎大家批评指正,不胜感激

java 线程交互之wait/notify