並行設計模式屬於設計優化的一部分,它是對一些常用的多線程結構的總結和抽象。與串行程序相比,並行程序的結構通常更爲複雜。因此合理的使用並行模式在開發中更有意義,目前在開發中應用最多的是Future,Master-Woker和生產者-消費者模式
一、Future模式
流程圖如下
public interface Data {
String 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 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 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);
}
}
一、Master-Woker模式
Master-Woker模式是常用的並行計算模式。它的核心思想是系統由兩類進程協作工作:Master進程Worker進程。Master負責接收和分配任務,Worker負責處理子任務。當各個子進程處理完成之後,會將結果返回給Master,由Master做歸納和總結。好處是能夠將一個大任務分解成若干個小任務,並執行,從而提高系統的吞吐量。
public class Master_Join {
// 1 有一個盛放任務的容器
private ConcurrentLinkedQueue<Task> workQuen = new ConcurrentLinkedQueue<>();
// 2 需要一個盛放worker的集合
private Map<String,Thread> workers = new HashMap<String,Thread>();
// 3 需要有一個盛放每一個worker執行任務的結果集合
private ConcurrentHashMap<String,Object> resultMap = new ConcurrentHashMap<>();
// 4 構造方法
public Master_Join( Worker worker,int workerCount ){
worker.setWorkQuen(this.workQuen);
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.workQuen.add(task);
}
// 6 需要有一個執行任務的方法,啓動所有的worker的方法並且執行
public void execute(){
for ( Map.Entry<String,Thread> worker : workers.entrySet()){
worker.getValue().start();
}
}
// 7 判斷是否運行結束的方法
public boolean isComplete(){
for ( Map.Entry<String,Thread> worker : workers.entrySet()){
if(worker.getValue().getState() != Thread.State.TERMINATED){
return false;
}
}
return true;
}
// 8 獲得計算結果的方法
public Double getResult(){
Double priceResult = 0d;
for(Map.Entry<String,Object> map : resultMap.entrySet()){
priceResult +=(Double) map.getValue();
}
return priceResult;
}
}
public class Task {
private Long id;
private String name;
private double price;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
public class Worker implements Runnable{
private ConcurrentLinkedQueue<Task> workQuen;
private ConcurrentHashMap<String,Object> resultMap;
public void setWorkQuen(ConcurrentLinkedQueue<Task> workQuen) {
this.workQuen = workQuen;
}
public void setResultMap(ConcurrentHashMap<String, Object> resultMap) {
this.resultMap = resultMap;
}
@Override
public void run() {
while (true){
Task input = this.workQuen.poll();
if(null == input){
break;
}
Object output = handle(input);
this.resultMap.put(Long.toString(input.getId()),output);
}
}
private Object handle(Task input) {
return null;
}
/* private Object handle(Task input) {
Object output = null;
try {
// 處理任務耗時。。。
Thread.sleep(300);
output = input.getPrice();
} catch (Exception e) {
e.printStackTrace();
}
return output ;
}*/
public class MyWorker extends Worker{
private Object handle(Task input) {
Object output = null;
try {
// 處理任務耗時。。。
Thread.sleep(300);
output = input.getPrice();
} catch (Exception e) {
e.printStackTrace();
}
return output ;
}
}
public class Main {
public static void main(String[] args) {
Master_Join master = new Master_Join(new Worker(),20);
Random random = new Random();
for(long i = 0; i < 100; i++){
Task task = new Task();
task.setId(i);
task.setPrice(random.nextInt(1500));
master.submit(task);
}
master.execute();
Instant instant = Instant.now();
while (true){
if(master.isComplete()){
Instant instant1 = Instant.now();
Double result = master.getResult();
long seconds = Duration.between(instant1, instant).getNano();
System.out.println("最終結果:"+result+ "耗時:"+ seconds);
break;
}
}
}
}