Java并发编程_wait和notify的使用

Posted 王晓东

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java并发编程_wait和notify的使用相关的知识,希望对你有一定的参考价值。

 

 

package sync;

import java.util.ArrayList;
import java.util.List;

public class WaitAndNotify {

	private volatile static List list= new ArrayList();
	
	private void add() {
		list.add("wang");
	}
	
	private int size() {
		return list.size();
	}
	
	
	public static void main(String[] args) {
		
		final WaitAndNotify list1 = new WaitAndNotify();
		/*
		 * 1. 实例化一个Object对象当作锁,下面t1和t2竞争这把锁实现同步
		 * 2. Object下面会有wait、notify方法,(面试经常问:Object下面有哪些方法,)
		 * 3. 说明每个对象都有这两个方法,都可以当作锁
		 */
		final Object lock = new Object();
		
		Thread t1 = new Thread(new Runnable() {
			@Override
			public void run() {
				try {
					synchronized (lock) {
						for(int i = 0; i < 10; i++) {
							list1.add();
							System.out.println("当前线程:" + Thread.currentThread().getName() + "添加了一个元素");
							Thread.sleep(500);
							if(list1.size() == 5) {
								System.out.println("已经发出通知..");
								//notify不释放锁,for循环还会继续执行
								lock.notify();
							}
						}
					}
					
				} catch(InterruptedException e) {
					e.printStackTrace();
				}
				
				
			}
		}, "t1");
		
		Thread t2 = new Thread(new Runnable() {
			@Override
			public void run() {
				synchronized(lock) {
					/*
					 * 如果先执行t2线程,如果size不是5,就wait
					 * wait会释放锁
					 */
					if(list1.size() != 5) {
						try {
							System.out.println("t2进入..");
							Thread.sleep(3000);
							lock.wait();
						}catch(InterruptedException e) {
							e.printStackTrace();
						}
					}
					//
					System.out.println("当前线程收到通知:" + Thread.currentThread().getName() + "list size = 5,线程停止");
					throw new RuntimeException();
				}
				
			}
		}, "t2");
		
		t2.start();
		t1.start();
	}
}

 

输出结果:

t2进入..
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
已经发出通知..
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
当前线程:t1添加了一个元素
当前线程收到通知:t2list size = 5,线程停止
Exception in thread "t2" java.lang.RuntimeException
	at sync.WaitAndNotify$2.run(WaitAndNotify.java:73)
	at java.lang.Thread.run(Unknown Source)

  

代码解读:

第一步:执行t2线程,进入run方法,list.size不等于5,就lock.wait释放锁,t2进程等待,转而执行t1

第二步:执行t1进程,得到锁,执行for循环,当list.size等于5时,发出通知..唤醒t2进程,但是会继续执行完for循环,因为notify不释放锁

第三步:t2进程被唤醒,因此list.size已经等于10,不等于5,直接输出最后两行代码

 

以上是关于Java并发编程_wait和notify的使用的主要内容,如果未能解决你的问题,请参考以下文章

Java并发编程(10):使用wait/notify/notifyAll实现线程间通信的几点重要说明

java并发编程使用wait/notify/notifyAll实现线程间通信

Java并发系列02Object的wait()notify()notifyAll()方法使用

转:Java并发编程之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明

Java并发编程原理与实战二十一:线程通信wait&notify&join

java并发编程线程间的通信notify通知的遗漏