Java多线程设计模式-学习笔记-Produce/Consumer模式.
来源:互联网 发布:mac上有啥游戏 编辑:程序博客网 时间:2024/06/05 15:01
1. 模式的形象描述:
生产者-消费者模式.
2. 模式的描述:
在这个模式中,有着建立Data参与者的线程(Producer参与者)与使用Data参与者的线程(Customer参与者)在运行,而现在要从Producer参与者,降Data参与者传递给Consumer参与者.
这时,在Producer参与者与Consumer参与者之间,安插额Channel参与者.并委托由Channel参与者来保管想要传递的Data参与者.Channel参与者的工作可说是Data参与者的中继站,桥梁以及沟通管道.
因为可能会有多个线程使用到Channel参与者,故Channel参与者中必须进行共享互斥.在Channel参与者中,”从Producer参与者接收Data参与者”与”传送Data参与者给Consumer参与者”的部分使用了Guarded Suspension Pattern..
3. 模式的参与者:
3.1 生产者-Producer:
产生数据的线程.
3.2 消费者-Consumer:
使用数据的线程.
3.3 数据对象-Data:
共享的数据,由Producer产生,在Consumer中使用.
3.4 沟通管道-Channel:
由生产者产生数据Data放到Channel中,消费者从Channel获取数据进行处理.
当程序存在多个Producer和Consumer的时候,Channel要进行共享互斥.
4. 示例程序:
4.1 示例的场景描述:
有3名厨师会一直作蛋糕放在桌上,而有3名客人会不停的吃.
4.2 Data参与者-蛋糕(String):
4.3 Producer参与者-厨师(MakerThread):
import java.util.Random;
/**
* <strong>Title : MakerThread<br></strong>
* <strong>Description : </strong>厨师类.<br>
* <strong>Create on : 2008-4-29<br></strong>
* <p>
* <strong>Copyright (C) QUF Software Co.,Ltd.<br></strong>
* <p>
* @author renxin renxin777@126.com<br>
* @version <strong>Java Thread Design Pattern Study</strong><br>
* <br>
* <strong>修改历史:</strong><br>
* 修改人 修改日期 修改描述<br>
* -------------------------------------------<br>
* <br>
* <br>
*/
public final class MakerThread extends Thread {
/**
* <code>m_random</code>-.
*/
private final Random m_random;
/**
* <code>m_table</code>-沟通管道.
*/
private final Table m_table;
/**
* <code>m_id</code>-蛋糕的随机号.
*/
private static int s_id;
/**
* 构造函数
* @param name - 线程的名称.
* @param table - 沟通管道.
* @param seed - 间隔的时间.
*/
public MakerThread(String name,Table table,long seed){
super(name);
this.m_table = table;
this.m_random = new Random(seed);
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
public void run(){
try {
while( true ) {
Thread.sleep(this.m_random.nextInt(1000));
String t_cake = " [Cake No.] " + nextId() + " by " + getName() +"";
this.m_table.put(t_cake);
}
} catch (InterruptedException e) {
// TODO: handle exception
}
}
/**
* 生成蛋糕的顺序号.
* @return 蛋糕的顺序号.
*/
private static synchronized int nextId(){
return s_id++;
}
}//END CLASS OF MakerThread.
4.4 Consumer参与者-客人(EaterThread):
import java.util.Random;
/**
* <strong>Title : EaterThread<br></strong>
* <strong>Description : </strong>顾客类.<br>
* <strong>Create on : 2008-4-29<br></strong>
* <p>
* <strong>Copyright (C) QUF Software Co.,Ltd.<br></strong>
* <p>
* @author renxin renxin777@126.com<br>
* @version <strong>Java Thread Design Pattern Study</strong><br>
* <br>
* <strong>修改历史:</strong><br>
* 修改人 修改日期 修改描述<br>
* -------------------------------------------<br>
* <br>
* <br>
*/
public final class EaterThread extends Thread {
private final Random m_random;
private final Table m_table;
/**
* 构造函数
* @param name - 线程名称.
* @param table - 沟通管道.
* @param seed - .
*/
public EaterThread(String name,Table table,long seed){
super(name);
this.m_random = new Random(seed);
this.m_table = table;
}
/* (non-Javadoc)
* @see java.lang.Thread#run()
*/
public void run() {
try {
while( true ){
this.m_table.take();
Thread.sleep(this.m_random.nextInt(1000));
}
} catch (InterruptedException e) {
// TODO: handle exception
}
}
}//END CLASS OF EaterThread.
4.5 Channel参与者-桌子(Table):
import java.io.Serializable;
import org.apache.log4j.Logger;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* <strong>Title : Table<br></strong>
* <strong>Description : </strong>沟通管道实现类<br>
* <strong>Create on : 2008-4-29<br></strong>
* <p>
* <strong>Copyright (C) QUF Software Co.,Ltd.<br></strong>
* <p>
* @author renxin renxin777@126.com<br>
* @version <strong>Java Thread Design Pattern Study</strong><br>
* <br>
* <strong>修改历史:</strong><br>
* 修改人 修改日期 修改描述<br>
* -------------------------------------------<br>
* <br>
* <br>
*/
public class Table implements Serializable {
/**
* <code>serialVersionUID</code>-注释
*/
private static final long serialVersionUID = -1212823669535279450L;
private static final Logger s_logger = Logger.getLogger(Table.class);
/**
* <code>m_buffer</code>-蛋糕存放的数组.
*/
private final String[] m_buffer;
/**
* <code>m_tail</code>-下一个put的地方.
*/
private int m_tail;
/**
* <code>m_head</code>-下一个take的地方.
*/
private int m_head;
/**
* <code>m_count</code>-buffer内的蛋糕数量.
*/
private int m_count;
/**
* 构造函数
*/
public Table(int count) {
// TODO Auto-generated constructor stub
this.m_buffer = new String[count];
this.m_head = 0;
this.m_count = 0;
}
/**
* 放蛋糕.
* @param cake - 蛋糕.
* @throws InterruptedException
*/
public synchronized void put(String cake) throws InterruptedException {
if ( s_logger.isDebugEnabled() ) {
s_logger.debug(Thread.currentThread().getName().concat("puts").concat(cake));
}
while( this.m_count >= this.m_buffer.length ) {
wait();
}
this.m_buffer[this.m_tail] = cake;
this.m_tail = (this.m_tail+1)%this.m_buffer.length;
this.m_count++;
notifyAll();
}
/**
* 获取蛋糕.
* @return 蛋糕.
* @throws InterruptedException
*/
public synchronized String take() throws InterruptedException{
while( this.m_count <= 0 ) {
wait();
}
String t_cake = this.m_buffer[this.m_head];
this.m_head = (this.m_head+1) % this.m_buffer.length;
this.m_count--;
notifyAll();
if ( s_logger.isDebugEnabled() ) {
s_logger.debug(Thread.currentThread().getName().concat("takes:").concat(t_cake));
}
System.out.println(Thread.currentThread().getName().concat(" takes:").concat(t_cake));
return t_cake;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return new ToStringBuilder(this).toString();
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return new HashCodeBuilder(-1073141277, -504257843).appendSuper(
super.hashCode()).append(this.m_count).append(this.m_tail)
.append(this.m_head).append(this.m_buffer).toHashCode();
}
}//END CLASS OF Table.
4.6 测试类-ProduceConsumerTest:
/**
* <strong>Title : ProduceConsumerTest<br></strong>
* <strong>Description : </strong>Produce-Consumer模式的测试类<br>
* <strong>Create on : 2008-4-29<br></strong>
* <p>
* <strong>Copyright (C) QUF Software Co.,Ltd.<br></strong>
* <p>
* @author renxin renxin777@126.com<br>
* @version <strong>Java Thread Design Pattern Study</strong><br>
* <br>
* <strong>修改历史:</strong><br>
* 修改人 修改日期 修改描述<br>
* -------------------------------------------<br>
* <br>
* <br>
*/
public class ProduceConsumerTest {
/**
* 构造函数
*/
public ProduceConsumerTest() {
// TODO Auto-generated constructor stub
}
/**
* 主方法.
* @param args
*/
public static void main( String[] args ){
Table t_table = new Table(3);
new MakerThread("MakerThread-1",t_table,31415).start();
new MakerThread("MakerThread-2",t_table,92653).start();
new MakerThread("MakerThread-3",t_table,58979).start();
new EaterThread("EaterThread-1",t_table,32384).start();
new EaterThread("EaterThread-2",t_table,62643).start();
new EaterThread("EaterThread-3",t_table,38327).start();
}
}//END CLASS OF ProduceConsumerTest .
5. 相关知识:
5.1 以什么顺序传递Data对象:
1. 队列.
2. 堆栈.
3. 优先队列.
5.2 线程互斥/合作:
1. 线程 的合作要想"放到中间的东西".
2. 线程互斥要想"应保护什么东西".
- Java多线程设计模式-学习笔记-Produce/Consumer模式.
- Java多线程设计模式详解学习笔记七——Producer-Consumer
- Java 多线程设计模式之Producer-Consumer
- java多线程设计模式之Producer-Consumer模式(一)
- java多线程设计模式之Producer-Consumer模式(二)
- 《java多线程设计模式 第五章Producer Consumer》
- 多线程设计模式之Producer Consumer
- Java多线程设计模式-学习笔记-Balking模式.
- Java多线程设计模式-学习笔记-Read/Write Lock模式.
- Java多线程设计模式-学习笔记-Thread Per Message模式.
- Java多线程设计模式学习笔记 - Java内存模型
- 多线程设计模式:Producer-Consumer生产者-消费者模式的C++
- 多线程设计模式——Producer-Consumer生产者消费者模式
- Java多线程设计模式详解学习笔记二
- 多线程设计模式之——Producer-Consumer Pattern
- Java设计模式 -- 学习笔记
- java设计模式学习笔记-工厂模式
- java设计模式学习笔记-构建模式
- 08年的新房子。
- CSS的各种浏览器兼容一栏表
- ArcSDE Oracle的存储DBTune配置
- ls命令(列出所有子目录与文件)
- 反其道为之,as3加载flex的swf
- Java多线程设计模式-学习笔记-Produce/Consumer模式.
- URL重写问题
- socket编程原理
- 来自EYGLE的帖子。
- C++设计模式之组合模式
- WinSDK
- 正则表达式30分钟入门教程
- 关于去美国
- Windows CE与Linux内存模型的比较