Java 并发(Future 模式)

 2023-09-17 阅读 29 评论 0

摘要:>Future 提前完成任务 首先,梳理一下,多线程为我们带来什么: 充分利用CPU当我们需要并行处理一件任务(并不一定是为了提高运算速度,而且很多时候性能并不是绝对的问题,同一时间需要处理多个任务,就要开线程) Futu

>Future 提前完成任务

首先,梳理一下,多线程为我们带来什么:

  • 充分利用CPU
  • 当我们需要并行处理一件任务(并不一定是为了提高运算速度,而且很多时候性能并不是绝对的问题,同一时间需要处理多个任务,就要开线程)

Future,未来,什么是未来?

设想一种情景,线程等待生产产品的时候,想做点其他的事情

产品:

public class Product {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Product [id=" + id + ", name=" + name + "]";}public Product() {}public Product(int id, String name) {this.id = id;this.name = name;new Thread(new Runnable() {@Overridepublic void run() {try {// 模拟产品生产过程Thread.sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}).start();}
}

java多线程并发处理?生产工厂:

public class ProductFactory {public Product buildProduct() {return new Product();}
}

测试线程:

public class Go {public static void main(String[] args) {ProductFactory pf=new ProductFactory();System.out.println("准备生产产品");Product product = pf.buildProduct();System.out.println("生产产品的时候,我想干点别的...");System.out.println("产品生产完毕"+product);}
}

结果:

准备生产产品
生产产品的时候,我想干点别的...
产品生产完毕Product [id=1, name=tea]

上面的代码的问题?

首先,为了模拟产品构建比较慢,我们使用Thread.sleep(),然后我们将Thread.sleep() 又放到了一个线程中,这是一种错误的代码,真正模拟生产产品,也就是初始化赋值的代码并没有办法拿到线程里面;

如果不能开线程,那么在真正产品生产结束之前,线程真就不能干点别的。

java实现并发的方式、另外,在构造函数中不能开线程,会造成This 逃逸现象(在对象构造完成之前,就发布了引用)。

再来,新问题:

如果现在要去蛋糕店定做一个蛋糕,蛋糕制作期间,想先处理下其他事情,先拿到订单,做好之后再拿到实际的蛋糕

建立模型:

为什么要设计成这个样子,首先找老板要定做一个蛋糕,需要一个返回值,老板一开始只能给我一个订单,蛋糕和订单 并不是同一个类型,所以要同时继承一个接口/共同继承一个类,这样满足类之间的多态。

单例模式并发?其中订单中对蛋糕存在一种包装,存在依赖关系,真正干活的还得是Real。

之前你拿蛋糕是直接在那等着做好了,直接拿蛋糕,现在有了这层 “订单包装”之后,既方便“老板”先给你一个订单,然后开线程把一个未完成的“订单”完成,同时你去做其他事情,也可以通过“订单”这个包装来控制:

  • 蛋糕未做完之前,来取就得等待,等做好了就通知你取“蛋糕”。
  • 蛋糕做好之后来取,直接就可以获得蛋糕。
/*** 数据访问接口*/
public interface Data {public String obtainString();
}
/*** 类似于产品 实际数据 "蛋糕"*/
public class Real implements Data {public Real() {try {//模拟产品生产过程Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic String obtainString() {//一旦可以调用返回,即代表产品生产完成return "hello world";}
}
/*** 可以理解为 "订单"*/
public class Future implements Data {private Real real;private boolean ready = false;public synchronized void setReal(Real real) {if (ready) {return;}this.real = real;this.ready = true;notifyAll();}@Overridepublic synchronized String obtainString() {if (!ready) {try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return real.obtainString();}
}
/*** 返回Data对象  可以理解为 "蛋糕店"*/
public class RequestHandler {public Data requestData() {final Future future = new Future();//开了一个线程去 做"蛋糕",可以想象这个线程需要运行一段时间new Thread(new Runnable() {@Overridepublic void run() {Real real = new Real();future.setReal(real);}}).start();//先给你一个订单return future;}
}
public class Go {public static void main(String[] args) throws InterruptedException {RequestHandler handler = new RequestHandler();//这里向"老板"handler 请求做蛋糕 ,拿到订单Data data1 = handler.requestData();Data data2 = handler.requestData();/*** 这里我们可以做其他事情,而不是等待*/System.out.println("我在做其他事情...");// Thread.sleep(3000);System.out.println(data1.obtainString());System.out.println(data2.obtainString());}
}

 

 

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/72533.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息