生产者消费者伪码_生产者-消费者模式的三种实现方式

本文详细介绍了生产者-消费者模式的三种实现方式:1)使用Object的wait和notify;2)使用Lock的Condition中await和signal;3)使用阻塞队列BlockingQueue。通过这种方式,实现了线程间的等待通知机制,达到了生产者和消费者的解耦,并讨论了相关同步和等待条件的处理。
摘要由CSDN通过智能技术生成

1、查看程序中线程的名称与状态

/**

* 4:Signal Dispatcher:RUNNABLE

* 3:Finalizer:WAITING

* 2:Reference Handler:WAITING

* 1:main:RUNNABLE

*/

@Test

public void testName(){

ThreadMXBean tb = ManagementFactory.getThreadMXBean();

ThreadInfo[] infos = tb.dumpAllThreads(false, false);

for(ThreadInfo info : infos){

System.out.println(info.getThreadId()+":"

+info.getThreadName()+":"

+info.getThreadState());

}

}

2、等待通知机制

一个线程修改一个对象的值,而另一个线程感知到了变化,然后进行相应的操作,这个过程始于一个线程,而最终执行又是另一个线程。前者是生产者,后者就是消费者。

生产者-消费者模式隔离了“做什么”和“怎么做”,在功能层面上实现了解耦,因此具备很好的扩展伸缩能力。

3、等待通知基本步骤

A:等待方和通知方遵循如下原则

1)获取对象的锁(生产者和消费者必须是同一把锁)

2)如果条件不满足,则执行锁的wait方法,等待被notify,notify后仍要继续检查条件,所以是while

3)如果条件满足,则执行对应的逻辑以及执行锁的notify。

B:伪代码

synchronized(lock){ // 获取对象的锁

while(list.size() - num < 0){ // 使用while做条件判断

try {

lock.wait(); // 条件不满足则等待

} catch (InterruptedException e) {

e.printStackTrace();

}

}

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

list.remove(0); // 改变条件

}

lock.notifyAll(); // 执行逻辑之后调用notify

}

4、生产者-消费者模式的具体实现

生产者-消费者模式的核心在于容器的容量,如果容器已经满了则通知生产者不要生产;如果容器已经空了则通知消费者不要继续消费。因此容器的加减应该做同步,容器的容量作为通知的条件。这其实就是阻塞队列的实现。

1)使用Object的 wait 和 notify 实现

2)使用Lock的condition中 await 和 signal 实现

3)使用阻塞队列实现

使用Object的 wait 和 notify 实现 如下:

package more_service.base_info;

import java.util.ArrayList;

import java.util.List;

public class ThreadWaitNotifyTest {

private static List list = new ArrayList();

private static final int MAX = 15;

private static Object lock = new Object();

public static void main(String[] args) {

Thread p1 = new Thread(new ProductThread(5));

Thread p2 = new Thread(new ProductThread(5));

Thread p3 = new Thread(new ProductThread(5));

Thread p4 = new Thread(new ProductThread(5));

Thread c1 = new Thread(new ConsumerThread(10));

Thread c2 = new Thread(new ConsumerThread(10));

c1.start();

c2.start();

p1.start();

p2.start();

p3.start();

p4.start();

}

public static void product(int num){

synchronized(lock){

while(list.size() + num > MAX){

try {

lock.wait();

System.out.println(Thread.currentThread().getName()+"---- 已经满了,不能继续生产");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

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

list.add(Thread.currentThread().getName()+":"+i);

System.out.println(Thread.currentThread().getName()+":"+i);

}

lock.notifyAll();

}

}

public static void consume(int num){

synchronized(lock){

while(list.size() - num < 0){

try {

lock.wait();

System.out.println(Thread.currentThread().getName()+"---- 已经空了,不能继续消费了");

} catch (InterruptedException e) {

e.printStackTrace();

}

}

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

System.out.println(Thread.currentThread().getName()+":"+list.remove(0));

}

lock.notifyAll();

}

}

static class ProductThread implements Runnable{

private int num;

public ProductThread(int num){

this.num = num;

}

public void run() {

product(this.num);

}

}

static class ConsumerThread implements Runnable{

private int num;

public ConsumerThread(int num){

this.num = num;

}

public void run() {

consume(this.num);

}

}

}

使用Lock的condition中 await 和 signal 实现如下:

/**

*

项目名称:mvn

*

Package名称:com.hnust.test

* 文件名称:LockTest.java

* 版本:1.00

* 创建日期:2015年9月13日

* Copyright©2014 HNUST .All Rights Reserved.

*/

package com.hnust.test;

import java.util.concurrent.locks.Condition;

import java.util.concurrent.locks.Lock;

import java.util.concurrent.locks.ReentrantLock;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**

*@author:Heweipo

*@version 1.00

*

*/

public class LockTest {

public static void main(String[] args) {

Data data = new Data();

MyTask1 t1 = new MyTask1(data);

MyTask2 t2 = new MyTask2(data);

t1.start();

t2.start();

}

}

class Data {

private int number = 0;

private Lock lock = new ReentrantLock();

private Condition c1 = lock.newCondition();

private Condition c2 = lock.newCondition();

public Data(){

System.out.println( c1 == c2);

lock = new ReentrantReadWriteLock().readLock();

}

public int increase(){

lock.lock();

try{

if(number != 0){

try {

c1.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

number++;

c2.signal();

}finally{

lock.unlock();

}

return number;

}

public int decrease(){

lock.lock();

try{

if(number != 1){

try {

c2.await();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

number--;

c1.signal();

}finally{

lock.unlock();

}

return number;

}

}

class MyTask1 extends Thread{

private Data data;

public MyTask1(Data data){

this.data = data;

}

public void run() {

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

System.out.println("decrease:"+data.decrease());

}

}

}

class MyTask2 extends Thread{

private Data data;

public MyTask2(Data data){

this.data = data;

}

public void run() {

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

System.out.println("increase:"+data.increase());

}

}

}

使用阻塞队列实现如下:

package more_service.base_info;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

import more_service.base_info.ThreadWaitNotifyTest.ConsumerThread;

import more_service.base_info.ThreadWaitNotifyTest.ProductThread;

public class BlockingQueueTest {

public static BlockingQueue queue = new LinkedBlockingQueue(3);

public static void main(String[] args) {

Thread p1 = new Thread(new ProductThread("1"));

Thread p2 = new Thread(new ProductThread("2"));

Thread p3 = new Thread(new ProductThread("3"));

Thread p4 = new Thread(new ProductThread("4"));

Thread c1 = new Thread(new ConsumerThread());

Thread c2 = new Thread(new ConsumerThread());

Thread c3 = new Thread(new ConsumerThread());

Thread c4 = new Thread(new ConsumerThread());

c1.start();

c2.start();

c3.start();

c4.start();

p1.start();

p2.start();

p3.start();

p4.start();

}

static class ProductThread implements Runnable{

private String name;

public ProductThread(String name){

this.name = name;

}

public void run() {

try {

System.out.println("put:"+name);

queue.put(name);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

static class ConsumerThread implements Runnable{

public void run() {

try {

System.out.println("take:"+queue.take());

} catch (InterruptedException e) {

e.printStackTrace();

}

}

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值