代码示例:

public interface Data {

    String getRequest();

}

public class FutureData implements Data{

    private RealData realData ;

    private boolean isReady = false;

    public synchronized void setRealData(RealData realData) {
//如果已经装载完毕了,就直接返回
if(isReady){
return;
}
//如果没装载,进行装载真实对象
this.realData = realData;
isReady = true;
//进行通知
notify();
} @Override
public synchronized String getRequest() {
//如果没装载好 程序就一直处于阻塞状态
while(!isReady){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//装载好直接获取数据即可
return this.realData.getRequest();
} } public class RealData implements Data{ private String result ; public RealData (String queryStr){
System.out.println("根据" + queryStr + "进行查询,这是一个很耗时的操作..");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("操作完毕,获取结果");
result = "查询结果";
} @Override
public String getRequest() {
return result;
} } public class FutureClient { public Data request(final String queryStr){
//1 我想要一个代理对象(Data接口的实现类)先返回给发送请求的客户端,告诉他请求已经接收到,可以做其他的事情
final FutureData futureData = new FutureData();
//2 启动一个新的线程,去加载真实的数据,传递给这个代理对象
new Thread(new Runnable() {
@Override
public void run() {
//3 这个新的线程可以去慢慢的加载真实对象,然后传递给代理对象
RealData realData = new RealData(queryStr);
futureData.setRealData(realData);
}
}).start(); return futureData;
} } public class Main { public static void main(String[] args) throws InterruptedException { FutureClient fc = new FutureClient();
Data data = fc.request("请求参数");
System.out.println("请求发送成功!");
System.out.println("做其他的事情..."); String result = data.getRequest();
System.out.println(result); }
}

具体一点,代码实现流程应该是这样的:

代码示例:

public class Task {

    private int id;
private int price ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
} } public class Master { //1 有一个盛放任务的容器
private ConcurrentLinkedQueue<Task> workQueue = new ConcurrentLinkedQueue<Task>(); //2 需要有一个盛放worker的集合
private HashMap<String, Thread> workers = new HashMap<String, Thread>(); //3 需要有一个盛放每一个worker执行任务的结果集合
private ConcurrentHashMap<String, Object> resultMap = new ConcurrentHashMap<String, Object>(); //4 构造方法
public Master(Worker worker , int workerCount){
worker.setWorkQueue(this.workQueue);
worker.setResultMap(this.resultMap); for(int i = 0; i < workerCount; i ++){
this.workers.put(Integer.toString(i), new Thread(worker));
} } //5 需要一个提交任务的方法
public void submit(Task task){
this.workQueue.add(task);
} //6 需要有一个执行的方法,启动所有的worker方法去执行任务
public void execute(){
for(Map.Entry<String, Thread> me : workers.entrySet()){
me.getValue().start();
}
} //7 判断是否运行结束的方法
public boolean isComplete() {
for(Map.Entry<String, Thread> me : workers.entrySet()){
if(me.getValue().getState() != Thread.State.TERMINATED){
return false;
}
}
return true;
} //8 计算结果方法
public int getResult() {
int priceResult = 0;
for(Map.Entry<String, Object> me : resultMap.entrySet()){
priceResult += (Integer)me.getValue();
}
return priceResult;
}
} public class Worker implements Runnable { private ConcurrentLinkedQueue<Task> workQueue;
private ConcurrentHashMap<String, Object> resultMap; public void setWorkQueue(ConcurrentLinkedQueue<Task> workQueue) {
this.workQueue = workQueue;
} public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
this.resultMap = resultMap;
} @Override
public void run() {
while(true){
Task input = this.workQueue.poll();
if(input == null) break;
Object output = handle(input);
this.resultMap.put(Integer.toString(input.getId()), output);
}
} private Object handle(Task input) {
Object output = null;
try {
//处理任务的耗时。。 比如说进行操作数据库。。。
Thread.sleep(500);
output = input.getPrice();
} catch (InterruptedException e) {
e.printStackTrace();
}
return output;
}
} public class Main { public static void main(String[] args) { Master master = new Master(new Worker(), 20); Random r = new Random();
for(int i = 1; i <= 100; i++){
Task t = new Task();
t.setId(i);
t.setPrice(r.nextInt(1000));
master.submit(t);
}
master.execute();
long start = System.currentTimeMillis(); while(true){
if(master.isComplete()){
long end = System.currentTimeMillis() - start;
int priceResult = master.getResult();
System.out.println("最终结果:" + priceResult + ", 执行时间:" + end);
break;
}
} }
}

代码示例:

public final class Data {

    private String id;
private String name; public Data(String id, String name){
this.id = id;
this.name = name;
} public String getId() {
return id;
} public void setId(String id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} @Override
public String toString(){
return "{id: " + id + ", name: " + name + "}";
}
} public class Consumer implements Runnable{ private BlockingQueue<Data> queue; public Consumer(BlockingQueue queue){
this.queue = queue;
} //随机对象
private static Random r = new Random(); @Override
public void run() {
while(true){
try {
//获取数据
Data data = this.queue.take();
//进行数据处理。休眠0 - 1000毫秒模拟耗时
Thread.sleep(r.nextInt(1000));
System.out.println("当前消费线程:" + Thread.currentThread().getName() + ", 消费成功,消费数据为id: " + data.getId());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
} public class Provider implements Runnable{ //共享缓存区
private BlockingQueue<Data> queue;
//多线程间是否启动变量,有强制从主内存中刷新的功能。即时返回线程的状态
private volatile boolean isRunning = true;
//id生成器
private static AtomicInteger count = new AtomicInteger();
//随机对象
private static Random r = new Random(); public Provider(BlockingQueue queue){
this.queue = queue;
} @Override
public void run() {
while(isRunning){
try {
//随机休眠0 - 1000 毫秒 表示获取数据(产生数据的耗时)
Thread.sleep(r.nextInt(1000));
//获取的数据进行累计...
int id = count.incrementAndGet();
//比如通过一个getData方法获取了
Data data = new Data(Integer.toString(id), "数据" + id);
System.out.println("当前线程:" + Thread.currentThread().getName() + ", 获取了数据,id为:" + id + ", 进行装载到公共缓冲区中...");
if(!this.queue.offer(data, 2, TimeUnit.SECONDS)){
System.out.println("提交缓冲区数据失败....");
//do something... 比如重新提交
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} public void stop(){
this.isRunning = false;
} } public class Main { public static void main(String[] args) throws Exception {
//内存缓冲区
BlockingQueue<Data> queue = new LinkedBlockingQueue<Data>(10);
//生产者
Provider p1 = new Provider(queue); Provider p2 = new Provider(queue);
Provider p3 = new Provider(queue);
//消费者
Consumer c1 = new Consumer(queue);
Consumer c2 = new Consumer(queue);
Consumer c3 = new Consumer(queue);
//创建线程池运行,这是一个缓存的线程池,可以创建无穷大的线程,没有任务的时候不创建线程。空闲线程存活时间为60s(默认值) ExecutorService cachePool = Executors.newCachedThreadPool();
cachePool.execute(p1);
cachePool.execute(p2);
cachePool.execute(p3);
cachePool.execute(c1);
cachePool.execute(c2);
cachePool.execute(c3); try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
p1.stop();
p2.stop();
p3.stop();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// cachePool.shutdown();
// cachePool.shutdownNow(); }
}

多线程的设计模式--Future模式,Master-Worker模式,生产者-消费者模式的更多相关文章

  1. Java设计模式—生产者消费者模式(阻塞队列实现)

    生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...

  2. java 多线程并发系列之 生产者消费者模式的两种实现

    在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题.该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据 ...

  3. Java生产者消费者模式

    为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程.在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能 ...

  4. python3全栈开发-多进程的守护进程、进程同步、生产者消费者模式(重点)

    一.守护进程 主进程创建守护进程 其一:守护进程会在主进程代码执行结束后就终止 其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes a ...

  5. Java并发(基础知识)—— 阻塞队列和生产者消费者模式

    1.阻塞队列                                                                                        Blocki ...

  6. java多线程系列15 设计模式 生产者 - 消费者模式

    生产者-消费者 生产者消费者模式是一个非常经典的多线程模式,比如我们用到的Mq就是其中一种具体实现 在该模式中 通常会有2类线程,消费者线程和生产者线程 生产者提交用户请求 消费者负责处理生产者提交的 ...

  7. Java并发程序设计(十一)设计模式与并发之生产者-消费者模式

    设计模式与并发之生产者-消费者模式 生产者-消费者模式是一个经典的多线程设计模式.它为多线程间的协作提供了良好的解决方案.在生产者-消费者模式中,通常由两类线程,即若干个生产者线程和若干个消费者线程. ...

  8. Java设计模式之生产者消费者模式

    Java设计模式之生产者消费者模式 博客分类: 设计模式 设计模式Java多线程编程thread 转载 对于多线程程序来说,不管任何编程语言,生产者和消费者模型都是最经典的.就像学习每一门编程语言一 ...

  9. Java的设计模式(7)— 生产者-消费者模式

    生产者-消费者模式是一个经典的多线程设计模式,它为多线程间的协作提供了良好的解决方案.这个模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程.生产者线程负责提交用户请求,消费者线程则负责具体 ...

  10. .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法

    1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...

随机推荐

  1. Drupal所能够理解的资源

    Drupal能够识别哪些资源类型? profile,不知道怎么翻译,应该是指安装类型,固定地存放于profiles目录下. module,模块,可以存在于多个目录下:modules.profiles/ ...

  2. 解决Jquery Ajax提交 服务器端接收中文乱码问题

    看到有朋友说到用post提交方式解决,我指定了methord="post",仍然解决不了, 说一下解决办法,客户端进行编码,服务器端解码, 客户端:var where = esca ...

  3. excel导入sql server 文本被截断,或者一个或多个字符在目标代码页中没有匹配项 错误处理

    excel导入sql server 文本被截断,或者一个或多个字符在目标代码页中没有匹配项 错误处理方法: 方案1:修改注册表 出现文本被截断的原因是SQL Server的导入导出为了确定数据表的字段 ...

  4. php中的重载以及几个常用的魔术方法示例

    在面向对象语言中,有一个很重要的概念——overload,即重载.所谓重载,一般是用于在一个类内实现若干重载的方法,这些方法的名称相同而参数形式不同.但是,在php中,这个概念跟大多面向对象语言中的“ ...

  5. unity, trail renderer gone black on iOS

    给物体加了个trail renderer,使用了Legacy Shaders/Transparent/Diffuse,并将颜色调成白色半透明.在编辑器里效果是对的,但在ios上真机测试变成黑色的.然后 ...

  6. worker

    <script id="worker" type="app/worker"> addEventListener('message', functio ...

  7. JVM虚拟机(一):java虚拟机的基本结构

    1: 类加载子系统(负责从文件系统或者网络中加载class信息,加载的类信息存放于一块成为方法区的内存空间.除了类信息外,方法区中可能还存放运行时常量池信息,包括字符串字面量和数字常量(这部分常量信息 ...

  8. HDU 3682 水模拟

    n*n*n的图形,m条线,每条线上的方格被删除.问一共删除了多少个方格 ans=m*n .然后推断一下直线相交的交点.去重就可以 #include "stdio.h" #inclu ...

  9. SecureCRT终端上使用spark-shell时按退格键无反应的解决方法

    问题:用SecureCRT远程连接至Spark集群,启动spark-shell却发现输错命令后却无法用退格键删除. 解决方法: 第一步: 在SecureCRT的菜单栏选择“OPtions(选项)”按钮 ...

  10. 关于UNIX/Linux下安装《UNIX环境高级编程》源代码的问题

    <UNIX环境高级编程(第三版)>是一本广为人知的unix系统编程书籍. 但是,书中的代码示例,要想正确的编译运行,要先做好准备工作: 1.下载源代码 传送门:http://apueboo ...