package com.tuling.learnjuc.sync.xiaoshanshan;
import java.util.LinkedList;
import java.util.Random;
public class ProducerAndConsumer {
public static void main(String[] args) {
Queue queue =new Queue(5);
new Thread(new Producer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
new Thread(new Consumer(queue)).start();
}
}
class Queue{
private Object[] array;
private int currentSize ;
private int putIndex ;
private int takeIndex ;
private static Object object = new Object();
public Queue(int capacity) {
array = new Object[capacity];
currentSize = 0;
}
// 放数据
public void put(Object o){
synchronized (object){
while(currentSize== array.length){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
array[putIndex] = o ;
if((putIndex+1)==array.length){
putIndex = 0;
}else{
putIndex = putIndex+1;
}
currentSize ++ ;
System.out.println(Thread.currentThread().getName() + "放入了"+o + "," + currentSize);
if(currentSize == array.length){
object.notifyAll();
}
}
}
// 取数据
public Object take(){
synchronized (object){
while(currentSize ==0){
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Object ret = array[takeIndex];
if(null==ret){
System.out.println("没有取到对象");
return null;
}
array[takeIndex] = null ;
if((takeIndex+1)==array.length){
takeIndex =0;
}else {
takeIndex = takeIndex+1 ;
}
currentSize -- ;
System.out.println(Thread.currentThread().getName() + "取出了"+ret + "," + currentSize);
if(currentSize == 0){
object.notifyAll();
}
return ret;
}
}
}
class Producer implements Runnable{
Queue queue ;
public Producer(Queue queue) {
this.queue = queue;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
queue.put(new Random().nextInt(1000));
}
}
}
class Consumer implements Runnable{
Queue queue ;
public Consumer(Queue queue) {
this.queue = queue;
}
@Override
public void run() {
while(true){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
queue.take();
}
}
}
注意:使用wait和notify实现等待通知的范式:
等待方遵循如下原则。
1)获取对象的锁。
2)如果条件不满足,那么调用对象的wait()方法,被通知后仍要检查条件。
3)条件满足则执行对应的逻辑
synchronized (对象){
while(条件不满足){
对象.wait();
}
对应的处理逻辑;
}
通知方遵循如下原则。
1)获得对象的锁。
2)改变条件。
3)通知所有等待在对象上的线程。
synchronized (对象){
改变条件;
对象.notifyAll();
}