一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java 高并發七:并發設計模型詳解

Java 高并發七:并發設計模型詳解

2020-06-14 11:39Hosee JAVA教程

本文主要介紹Java高并發 并發設計模型的知識,這里主要講解 1. 什么是設計模式 2. 單例模式 3. 不變模式 4. Future模式 5. 生產者消費者,有需要的小伙伴可以參考下

1. 什么是設計模式

在軟件工程中,設計模式(design pattern)是對軟件設計中普遍存在(反復出現)的各種問題 ,所提出的解決方案。這個術語是由埃里希·伽瑪(Erich Gamma)等人在1990年代從建筑設計領 域引入到計算機科學的。

著名的4人幫: Erich Gamma,Richard Helm, Ralph Johnson ,John Vlissides (Gof)

《設計模式:可復用面向對象軟件的基礎》收錄23種模式

2. 單例模式

單例對象的類必須保證只有一個實例存在。許多時候整個系統只需要擁有一個的全局對象,這樣有利于我們協調系統整體的行為

比如:全局信息配置

單例模式最簡單的實現:

?
1
2
3
4
5
6
7
8
9
public class Singleton {
 private Singleton() {
 System.out.println("Singleton is create");
 }
 private static Singleton instance = new Singleton();
 public static Singleton getInstance() {
 return instance;
 }
}

由私有構造方法和static來確定唯一性。

缺點:何時產生實例 不好控制

雖然我們知道,在類Singleton第一次被加載的時候,就產生了一個實例。

但是如果這個類中有其他屬性

?
1
2
3
4
5
6
7
8
9
10
public class Singleton {
 public static int STATUS=1;
 private Singleton() {
 System.out.println("Singleton is create");
 }
 private static Singleton instance = new Singleton();
 public static Singleton getInstance() {
 return instance;
 }
}

當使用

System.out.println(Singleton.STATUS);

這個實例就被產生了。也許此時你并不希望產生這個實例。

如果系統特別在意這個問題,這種單例的實現方法就不太好。

第二種單例模式的解決方式:

?
1
2
3
4
5
6
7
8
9
10
11
public class Singleton {
 private Singleton() {
 System.out.println("Singleton is create");
 }
 private static Singleton instance = null;
 public static synchronized Singleton getInstance() {
 if (instance == null)
 instance = new Singleton();
 return instance;
 }
}

讓instance只有在調用getInstance()方式時被創建,并且通過synchronized來確保線程安全。
這樣就控制了何時創建實例。

這種方法是延遲加載的典型。

但是有一個問題就是,在高并發的場景下性能會有影響,雖然只有一個判斷就return了,但是在并發量很高的情況下,或多或少都會有點影響,因為都要去拿synchronized的鎖。

為了高效,有了第三種方式:

?
1
2
3
4
5
6
7
8
9
10
11
public class StaticSingleton {
 private StaticSingleton(){
 System.out.println("StaticSingleton is create");
 }
 private static class SingletonHolder {
 private static StaticSingleton instance = new StaticSingleton();
 }
 public static StaticSingleton getInstance() {
 return SingletonHolder.instance;
 }
}

由于加載一個類時,其內部類不會被加載。這樣保證了只有調用getInstance()時才會產生實例,控制了生成實例的時間,實現了延遲加載。

并且去掉了synchronized,讓性能更優,用static來確保唯一性。

3. 不變模式

一個類的內部狀態創建后,在整個生命期間都不會發生變化時,就是不變類

不變模式不需要同步

創建一個不變的類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
public final class Product {
 // 確保無子類
 private final String no;
 // 私有屬性,不會被其他對象獲取
 private final String name;
 // final保證屬性不會被2次賦值
 private final double price;
 
 public Product(String no, String name, double price) {
 // 在創建對象時,必須指定數據
 super();
 // 因為創建之后,無法進行修改
 this.no = no;
 this.name = name;
 this.price = price;
 }
 
 public String getNo() {
 return no;
 }
 
 public String getName() {
 return name;
 }
 
 public double getPrice() {
 return price;
 }
 
}

Java中不變的模式的案例有:

java.lang.String
java.lang.Boolean
java.lang.Byte
java.lang.Character
java.lang.Double
java.lang.Float
java.lang.Integer
java.lang.Long
java.lang.Short 

4. Future模式

核心思想是異步調用

非異步:

Java 高并發七:并發設計模型詳解

異步:

Java 高并發七:并發設計模型詳解

第一次的call_return由于任務還沒完成,所以返回的是一個空的。

但是這個返回類似于購物中的訂單,將來可以根據這個訂單來得到一個結果。

所以這個Future模式意思就是,“未來”可以得到,就是指這個訂單或者說是契約,“承諾”未來就會給結果。

Future模式簡單的實現:

Java 高并發七:并發設計模型詳解

調用者得到的是一個Data,一開始可能是一個FutureData,因為RealData構建很慢。在未來的某個時間,可以通過FutureData來得到RealData。

代碼實現:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public interface Data {
 public String getResult ();
}
public class FutureData implements Data {
 protected RealData realdata = null; //FutureData是RealData的包裝
 protected boolean isReady = false;
 public synchronized void setRealData(RealData realdata) {
 if (isReady) {
 return;
 }
 this.realdata = realdata;
 isReady = true;
 notifyAll(); //RealData已經被注入,通知getResult()
 }
 public synchronized String getResult()//會等待RealData構造完成
 {
 while (!isReady) {
 try
 wait(); //一直等待,知道RealData被注入
 } catch (InterruptedException e) {
 }
 }
 return realdata.result; //由RealData實現
 }
}
public class RealData implements Data {
 protected final String result;
 public RealData(String para) {
 // RealData的構造可能很慢,需要用戶等待很久,這里使用sleep模擬
 StringBuffer sb = new StringBuffer();
 for (int i = 0; i < 10; i++) {
 sb.append(para);
 try {
 // 這里使用sleep,代替一個很慢的操作過程
 Thread.sleep(100);
 } catch (InterruptedException e) {
 }
 }
 result = sb.toString();
 }
 public String getResult() {
 return result;
 }
}
public class Client {
 public Data request(final String queryStr) {
 final FutureData future = new FutureData();
 new Thread() {
 public void run()
 {
 // RealData的構建很慢,
 //所以在單獨的線程中進行
 RealData realdata = new RealData(queryStr); 
 future.setRealData(realdata);
 }   
 }.start();
 return future; // FutureData會被立即返回
 }
}
public static void main(String[] args) {
 Client client = new Client();
 // 這里會立即返回,因為得到的是FutureData而不是RealData
 Data data = client.request("name");
 System.out.println("請求完畢");
 try {
 // 這里可以用一個sleep代替了對其他業務邏輯的處理
 // 在處理這些業務邏輯的過程中,RealData被創建,從而充分利用了等待時間
 Thread.sleep(2000);
 } catch (InterruptedException e) {
 }
 // 使用真實的數據
 System.out.println("數據 = " + data.getResult());
 }

JDK中也有多Future模式的支持:

Java 高并發七:并發設計模型詳解

接下來使用JDK提供的類和方法來實現剛剛的代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.concurrent.Callable;
 
public class RealData implements Callable<String> {
 private String para;
 
 public RealData(String para) {
 this.para = para;
 }
 
 @Override
 public String call() throws Exception {
 StringBuffer sb = new StringBuffer();
 for (int i = 0; i < 10; i++) {
 sb.append(para);
 try {
 Thread.sleep(100);
 } catch (InterruptedException e) {
 
 }
 }
 return sb.toString();
 }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
 
public class FutureMain {
 public static void main(String[] args) throws InterruptedException,
 ExecutionException {
 // 構造FutureTask
 FutureTask<String> future = new FutureTask<String>(new RealData("a"));
 ExecutorService executor = Executors.newFixedThreadPool(1);
 // 執行FutureTask,相當于上例中的 client.request("a") 發送請求
 // 在這里開啟線程進行RealData的call()執行
 executor.submit(future);
 System.out.println("請求完畢");
 try {
 // 這里依然可以做額外的數據操作,這里使用sleep代替其他業務邏輯的處理
 Thread.sleep(2000);
 } catch (InterruptedException e) {
 }
 // 相當于data.getResult (),取得call()方法的返回值
 // 如果此時call()方法沒有執行完成,則依然會等待
 System.out.println("數據 = " + future.get());
 }
}

這里要注意的是FutureTask是即具有 Future功能又具有Runnable功能的類。所以又可以運行,最后還能get。
當然如果在調用到future.get()時,真實數據還沒準備好,仍然會產生阻塞狀況,直到數據準備完成。

當然還有更加簡便的方式:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
public class FutureMain2 {
 public static void main(String[] args) throws InterruptedException,
 ExecutionException {
 ExecutorService executor = Executors.newFixedThreadPool(1);
 // 執行FutureTask,相當于上例中的 client.request("a") 發送請求
 // 在這里開啟線程進行RealData的call()執行
 Future<String> future = executor.submit(new RealData("a"));
 System.out.println("請求完畢");
 try {
 // 這里依然可以做額外的數據操作,這里使用sleep代替其他業務邏輯的處理
 Thread.sleep(2000);
 } catch (InterruptedException e) {
 }
 // 相當于data.getResult (),取得call()方法的返回值
 // 如果此時call()方法沒有執行完成,則依然會等待
 System.out.println("數據 = " + future.get());
 }
}

由于Callable是有返回值的,可以直接返回future對象。

5. 生產者消費者

生產者-消費者模式是一個經典的多線程設計模式。它為多線程間的協作提供了良好的解決方案。 在生產者-消費者模式中,通常由兩類線程,即若干個生產者線程和若干個消費者線程。生產者線 程負責提交用戶請求,消費者線程則負責具體處理生產者提交的任務。生產者和消費者之間則通 過共享內存緩沖區進行通信。

以前寫過一篇用Java來實現生產者消費者的多種方法,這里就不多闡述了。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 欧美一区二区三区免费看 | 亚洲高清无码在线 视频 | 人人人人看人人人做人人 | 国产私拍精品88福利视频 | 国产成人精品曰本亚洲77美色 | 婷婷色六月 | 538免费精品视频搬运工 | 久久日韩精品无码一区 | 动漫美丽妇人1~2在线看 | 国产成人免费片在线视频观看 | 四虎影院永久网址 | 潘金莲西门庆一级淫片aaaaaa | 亚洲AV无码乱码国产麻豆穿越 | 色老板在线免费视频 | 亚洲AV蜜桃永久无码精品无码网 | 国内精品久久久久影院中国 | 无人区大片免费播放器 | 亚洲欧美国产另类 | 欧美成人aletta ocean | 国产自拍视频一区 | 国产欧美日韩一区二区三区在线 | 欧美精品99久久久久久人 | 青青99| 国产欧美又粗又猛又爽老 | 免费的毛片视频 | 色播艾小青国产专区在线播放 | 亚洲 日韩经典 中文字幕 | 91成人啪国产啪永久地址 | 美女机机对机机的视频(免费) | 国产最强大片免费视频 | 法国老妇性xx在线播放 | 亚洲成人福利网站 | 女人被爽到呻吟娇喘的视频动态图 | 亚洲精品乱码久久久久久蜜桃欧美 | 亚洲波多野结衣日韩在线 | 成人高辣h视频一区二区在线观看 | 我的妹妹最近有点怪在线观看 | 日本特黄一级午夜剧场毛片 | 呜嗯啊野战h呻吟男男双性 污小说在线阅读 | 色先锋 影音先锋a 资源站 | 欧美色图日韩 |