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();
}
}
}
}