`
zengshaotao
  • 浏览: 752668 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

生产者消费者进阶(带有condition)

 
阅读更多

package function.thread;

 

import java.util.ArrayList;

import java.util.Arrays;

import java.util.List;

import java.util.Random;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

/**

功能:三个生产者,往容量最大为5的容器里put数据

三个消费者从容器中取数据。只要容器不为空,就可以取数据,

只要容器不满,就可以存放数据

容器里不能拥有相同的数据

*/

public class ConditionTest {

 

public static void main(String args[]) {

 

final String goonFlag[] = {"true"};

final BoundedBuffer bf = new BoundedBuffer();

System.out.println("**************************************** main thread begin********************************");

//刚开始是抢占式的,take和put线程都可能先执行

for (int i = 0; i < 3; i++) {

new Thread(" put thread "+i) {

public void run() {

try {

//这里是匿名的内部类,所以要使用final变量

while(goonFlag[0].equals("true")){

bf.put(new Random().nextInt(100));

}

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}.start();

 

new Thread(" take thread "+i) {

public void run() {

try {

while(goonFlag[0].equals("true")){

try {

bf.take();

} catch (Exception e) {

e.printStackTrace();

}

}

} catch (Exception e) {

e.printStackTrace();

}

}

}.start();

}

 

try {

Thread.sleep(30000);

goonFlag[0]= "false";

} catch (InterruptedException e) {

e.printStackTrace();

}

}//main method

}

 

class BoundedBuffer {

final Lock lock = new ReentrantLock();// 锁对象

final Condition putCond = lock.newCondition();// 队列未满,写线程可以满足执行条件

final Condition takeCond = lock.newCondition();// 读线程条件

 

final List items = new ArrayList();// 缓存队列

 

public void put(Object x) throws InterruptedException {

lock.lock();

String threadName = Thread.currentThread().getName();

System.out.println("############### 【"+threadName+"】 get lock and sleep 500 ms ");

Thread.sleep(500);

try {

if (items.size()>=5){

System.out.println("############### 【"+threadName+"】 stack is full and await ");

takeCond.signalAll();//队列已经满了,读线程可以进行读取了

// 阻塞写线程

//一个线程被阻塞,从业务角度理解,它的使命已经完成

//如果要重新参与作业,就要重新参与线程的竞争

putCond.await();

}else{

if(!items.contains(x)){

items.add(x);// 赋值

System.out.println("############### 【"+threadName+"】 put: "+x);

System.out.println("############### 【"+threadName+"】 list length "+items.size()+", list content:"+items.toString());

takeCond.signalAll();//队列不为空,读线程可以进行读取了

}else{

System.out.println("############### 【"+threadName+"】 put same: "+x);

System.out.println("############### 【"+threadName+"】 list content:"+items.toString());

}

 

}

 

} finally {

System.out.println("############### 【"+threadName+"】 release the lock ");

lock.unlock();

}

}

 

public Object take() throws Exception {

lock.lock();

String threadName = Thread.currentThread().getName();

//int listSize = items.size();不能使用局部变量,因为如果使用,得到的可能是await之前的值

//await期间,该值可能已经被修改

System.out.println("**************** 【"+threadName+"】 get a lock and sleep 500ms ");

Thread.sleep(500);

try {

if (items.size() == 0){

System.out.println("**************** 【"+threadName+"】 stack is empty and await ");

putCond.signalAll();// 队列为空,就可以继续写入,也就是可以唤醒写线程

//当前线程调用了condition,被打上了相应的标签

//阻塞读线程。这里需要注意,被贴上了参与共享资源标签的线程在被唤醒后,

//可能会和还未打上标签的线程竞争。还有一种就是被打上了标签之后的多个线程同时竞争

takeCond.await();

return null;

}else{

Object x = items.get(items.size()-1);// 取值

System.out.println("**************** 【"+threadName+"】 get the value: "+x);

items.remove(x);

System.out.println("**************** 【"+threadName+"】 remain list : "+items.toString());

putCond.signalAll();// 队列未满,就可以继续写入,也就是可以唤醒写线程

return x;

}

 

 

}catch(Exception e){

e.printStackTrace();

return null;

}finally {

System.out.println("**************** 【"+threadName+"】 release the lock ");

lock.unlock();

}

}

}

 

运行结果:

**************************************** main thread begin********************************

############### 【 put thread 0】 get lock and sleep 500 ms 

############### 【 put thread 0】 put: 66

############### 【 put thread 0】 list length 1, list content:[66]

############### 【 put thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 66

**************** 【 take thread 0】 remain list : []

**************** 【 take thread 0】 release the lock 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 57

############### 【 put thread 1】 list length 1, list content:[57]

############### 【 put thread 1】 release the lock 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 94

############### 【 put thread 1】 list length 2, list content:[57, 94]

############### 【 put thread 1】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 90

############### 【 put thread 2】 list length 3, list content:[57, 94, 90]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 23

############### 【 put thread 2】 list length 4, list content:[57, 94, 90, 23]

############### 【 put thread 2】 release the lock 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 23

**************** 【 take thread 1】 remain list : [57, 94, 90]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 2】 get a lock and sleep 500ms 

**************** 【 take thread 2】 get the value: 90

**************** 【 take thread 2】 remain list : [57, 94]

**************** 【 take thread 2】 release the lock 

############### 【 put thread 0】 get lock and sleep 500 ms 

############### 【 put thread 0】 put: 77

############### 【 put thread 0】 list length 3, list content:[57, 94, 77]

############### 【 put thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 77

**************** 【 take thread 0】 remain list : [57, 94]

**************** 【 take thread 0】 release the lock 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 74

############### 【 put thread 1】 list length 3, list content:[57, 94, 74]

############### 【 put thread 1】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put same: 94

############### 【 put thread 2】 list content:[57, 94, 74]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 28

############### 【 put thread 2】 list length 4, list content:[57, 94, 74, 28]

############### 【 put thread 2】 release the lock 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 28

**************** 【 take thread 1】 remain list : [57, 94, 74]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 74

**************** 【 take thread 1】 remain list : [57, 94]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 2】 get a lock and sleep 500ms 

**************** 【 take thread 2】 get the value: 94

**************** 【 take thread 2】 remain list : [57]

**************** 【 take thread 2】 release the lock 

############### 【 put thread 0】 get lock and sleep 500 ms 

############### 【 put thread 0】 put: 15

############### 【 put thread 0】 list length 2, list content:[57, 15]

############### 【 put thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 15

**************** 【 take thread 0】 remain list : [57]

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 57

**************** 【 take thread 0】 remain list : []

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 stack is empty and await 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 78

############### 【 put thread 1】 list length 1, list content:[78]

############### 【 put thread 1】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 70

############### 【 put thread 2】 list length 2, list content:[78, 70]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 40

############### 【 put thread 2】 list length 3, list content:[78, 70, 40]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 49

############### 【 put thread 2】 list length 4, list content:[78, 70, 40, 49]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 60

############### 【 put thread 2】 list length 5, list content:[78, 70, 40, 49, 60]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 stack is full and await 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 60

**************** 【 take thread 1】 remain list : [78, 70, 40, 49]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 49

**************** 【 take thread 1】 remain list : [78, 70, 40]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 2】 get a lock and sleep 500ms 

**************** 【 take thread 2】 get the value: 40

**************** 【 take thread 2】 remain list : [78, 70]

**************** 【 take thread 2】 release the lock 

############### 【 put thread 0】 get lock and sleep 500 ms 

############### 【 put thread 0】 put: 31

############### 【 put thread 0】 list length 3, list content:[78, 70, 31]

############### 【 put thread 0】 release the lock 

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 31

**************** 【 take thread 0】 remain list : [78, 70]

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 70

**************** 【 take thread 0】 remain list : [78]

**************** 【 take thread 0】 release the lock 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 23

############### 【 put thread 1】 list length 2, list content:[78, 23]

############### 【 put thread 1】 release the lock 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 91

############### 【 put thread 1】 list length 3, list content:[78, 23, 91]

############### 【 put thread 1】 release the lock 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 57

############### 【 put thread 1】 list length 4, list content:[78, 23, 91, 57]

############### 【 put thread 1】 release the lock 

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 22

############### 【 put thread 2】 list length 5, list content:[78, 23, 91, 57, 22]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 stack is full and await 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 22

**************** 【 take thread 1】 remain list : [78, 23, 91, 57]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 2】 get a lock and sleep 500ms 

**************** 【 take thread 2】 get the value: 57

**************** 【 take thread 2】 remain list : [78, 23, 91]

**************** 【 take thread 2】 release the lock 

############### 【 put thread 0】 get lock and sleep 500 ms 

############### 【 put thread 0】 put: 20

############### 【 put thread 0】 list length 4, list content:[78, 23, 91, 20]

############### 【 put thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 20

**************** 【 take thread 0】 remain list : [78, 23, 91]

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 91

**************** 【 take thread 0】 remain list : [78, 23]

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 23

**************** 【 take thread 0】 remain list : [78]

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 78

**************** 【 take thread 0】 remain list : []

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 stack is empty and await 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 77

############### 【 put thread 1】 list length 1, list content:[77]

############### 【 put thread 1】 release the lock 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 5

############### 【 put thread 1】 list length 2, list content:[77, 5]

############### 【 put thread 1】 release the lock 

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 57

############### 【 put thread 2】 list length 3, list content:[77, 5, 57]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 27

############### 【 put thread 2】 list length 4, list content:[77, 5, 57, 27]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 put: 32

############### 【 put thread 2】 list length 5, list content:[77, 5, 57, 27, 32]

############### 【 put thread 2】 release the lock 

############### 【 put thread 2】 get lock and sleep 500 ms 

############### 【 put thread 2】 stack is full and await 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 32

**************** 【 take thread 1】 remain list : [77, 5, 57, 27]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 27

**************** 【 take thread 1】 remain list : [77, 5, 57]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 57

**************** 【 take thread 1】 remain list : [77, 5]

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 2】 get a lock and sleep 500ms 

**************** 【 take thread 2】 get the value: 5

**************** 【 take thread 2】 remain list : [77]

**************** 【 take thread 2】 release the lock 

**************** 【 take thread 2】 get a lock and sleep 500ms 

**************** 【 take thread 2】 get the value: 77

**************** 【 take thread 2】 remain list : []

**************** 【 take thread 2】 release the lock 

############### 【 put thread 0】 get lock and sleep 500 ms 

############### 【 put thread 0】 put: 28

############### 【 put thread 0】 list length 1, list content:[28]

############### 【 put thread 0】 release the lock 

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 get the value: 28

**************** 【 take thread 0】 remain list : []

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 0】 get a lock and sleep 500ms 

**************** 【 take thread 0】 stack is empty and await 

############### 【 put thread 1】 get lock and sleep 500 ms 

############### 【 put thread 1】 put: 92

############### 【 put thread 1】 list length 1, list content:[92]

############### 【 put thread 1】 release the lock 

############### 【 put thread 2】 release the lock 

**************** 【 take thread 1】 get a lock and sleep 500ms 

**************** 【 take thread 1】 get the value: 92

**************** 【 take thread 1】 remain list : []

**************** 【 take thread 1】 release the lock 

**************** 【 take thread 2】 get a lock and sleep 500ms 

**************** 【 take thread 2】 stack is empty and await 

############### 【 put thread 0】 get lock and sleep 500 ms 

############### 【 put thread 0】 put: 20

############### 【 put thread 0】 list length 1, list content:[20]

############### 【 put thread 0】 release the lock 

**************** 【 take thread 0】 release the lock 

**************** 【 take thread 2】 release the lock 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics