wait() notify使用注意事项

1.wait被调用之前notify的唤醒通知就来了,那么这个线程并不能保证被唤醒,有可能会导致死锁问题

2.不要使用if(队列size>最大个数) 否则真的会出现放入队列的size个数超过最大值的情况,推荐使用while

3.不要使用notify,推荐使用notifyall()

下面是生产者和消费者线程死锁方式和正确方式

package thred;

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

import com.alibaba.fastjson.JSONObject;


/**
 * 线程间通信
 * 执行结果
* @Description: TODO(用一句话描述该文件做什么) 
* @author min.zhang-2   
* @date 2017年12月19日 上午9:39:53 
* @version V1.0
 */
public class TestWaitNotify {

	public static void main(String[] args) {
		/*对应下面的注释1的类,如果生产者先过来,生产者想唤醒消费者,没有线程被阻塞唤醒结束
		消费者还没有被阻塞,这时候他请求过来,消费者线程被阻塞!!!!!
		执行结果:消费者等待吃苹果
		*/
		/*String nameString  = "test";
		Coustem Coustem =  new Coustem(nameString);
		Producer Producer = new Producer(nameString);
		
		Coustem.start();
		Producer.start();*/
		
		/***
		 * 实现了线程间通信的生产者和消费者,运行结果
		 * 
		 *  使用notifyall()的时候
		 *  生产者生产了2个2["3","3"]
			消费者消费掉了一个1["3"]
			消费者消费掉了一个0[]
			消费者开始等待
			生产者生产了2个2["3","3"]
			消费者消费掉了一个1["3"]
			消费者消费掉了一个0[]
			消费者开始等待
			
			使用notify的时候,总是等待生产者满了等待之后才唤醒消费者,为啥呢?,所以推荐使用notifyall()
			生产者生产了2个2["3","3"]
			生产者生产了2个4["3","3","3","3"]
			生产者生产了2个6["3","3","3","3","3","3"]
			生产者生产了2个8["3","3","3","3","3","3","3","3"]
			生产者生产了2个10["3","3","3","3","3","3","3","3","3","3"]
			生产仓库已经满了10开始等待
			消费者消费掉了一个9["3","3","3","3","3","3","3","3","3"]
		 */
		List<String> obList = new ArrayList<String>();
		Coustem Coustem =  new Coustem(obList);
		Producer Producer =  new Producer(obList);
		Producer.start();
		Coustem.start();
	}

}

/*****************这种方式就是死循环了*************/
/*class Coustem extends Thread{
	private Object lock;
	
	public Coustem(Object lock){
		this.lock=lock;
	}
	
	@Override
	public void run() {
		synchronized(lock) {
			try {
				System.out.println("消费者等待吃苹果");
				lock.wait();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("消费者部分结束");
		}
	}
}

class Producer extends Thread{
	private Object lock;
	
	public Producer(Object lock){
		this.lock=lock;
	}
	
	@Override
	public void run() {
		
		synchronized(lock) {
			System.out.println("生产者生产了一个苹果");
			lock.notify();
			System.out.println("生产者部分结束");
		}
	}
}*/

/*********************************对应main的第二段 ,实现了生产者消费者**********/
class Producer extends Thread{
	private List<String> lock;
	
	public Producer(List<String> lock){
		this.lock=lock;
	}
	
	@Override
	public void run() {
		while(true){
			synchronized(lock){
				while(lock.size() >= 10) {
					System.out.println("生产仓库已经满了"+lock.size()+"开始等待");
					try {
						lock.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				lock.add("3");
				lock.add("3");
				System.out.println("生产者生产了2个"+lock.size()+JSONObject.toJSONString(lock));
				lock.notify();
			}
		}
	}
}

class Coustem extends Thread{
	private List<String> lock;
	
	public Coustem(List<String> lock){
		this.lock=lock;
	}
	
	@Override
	public void run() {
		while(true){
			synchronized (lock) {
				while(lock.size() == 0) {
					System.out.println("消费者开始等待");
					try {
						lock.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				lock.remove("3");
				System.out.println("消费者消费掉了一个"+lock.size()+JSONObject.toJSONString(lock));
				lock.notify();
			}
		}
	}
}



猜你喜欢

转载自blog.csdn.net/zhangxiaomin1992/article/details/78870552