首页 > 代码库 > 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