更新時(shí)間:2022-04-07 16:58:57 來源:動(dòng)力節(jié)點(diǎn) 瀏覽1729次
Java并發(fā)(多線程)。本文介紹如何使用Java進(jìn)行并發(fā)編程。它涵蓋了并行編程、不變性、線程、執(zhí)行器框架(線程池)、期貨、可調(diào)用的CompletableFuture和fork-join框架的概念。

并發(fā)是并行運(yùn)行多個(gè)程序或程序的幾個(gè)部分的能力。如果一項(xiàng)耗時(shí)的任務(wù)可以異步或并行執(zhí)行,這將提高程序的吞吐量和交互性。
現(xiàn)代計(jì)算機(jī)在一個(gè)CPU中具有多個(gè)CPU或多個(gè)內(nèi)核。利用這些多核的能力可能是成功的大容量應(yīng)用程序的關(guān)鍵。
一個(gè)進(jìn)程獨(dú)立運(yùn)行并與其他進(jìn)程隔離。它不能直接訪問其他進(jìn)程中的共享數(shù)據(jù)。進(jìn)程的資源,例如內(nèi)存和CPU時(shí)間,是通過操作系統(tǒng)分配給它的。
線程是所謂的輕量級(jí)進(jìn)程。它有自己的調(diào)用棧,但可以訪問同一進(jìn)程中其他線程的共享數(shù)據(jù)。每個(gè)線程都有自己的內(nèi)存緩存。如果一個(gè)線程讀取共享數(shù)據(jù),它會(huì)將這些數(shù)據(jù)存儲(chǔ)在自己的內(nèi)存緩存中。
線程可以重新讀取共享數(shù)據(jù)。
默認(rèn)情況下,Java應(yīng)用程序在一個(gè)進(jìn)程中運(yùn)行。在Java應(yīng)用程序中,您使用多個(gè)線程來實(shí)現(xiàn)并行處理或異步行為。
在Java應(yīng)用程序中,您使用多個(gè)線程來實(shí)現(xiàn)并行處理或異步行為。并發(fā)承諾更快地執(zhí)行某些任務(wù),因?yàn)檫@些任務(wù)可以分為子任務(wù),并且這些子任務(wù)可以并行執(zhí)行。當(dāng)然,運(yùn)行時(shí)間受到可以并行執(zhí)行的任務(wù)部分的限制。
理論上可能的性能增益可以通過以下稱為阿姆達(dá)爾定律的規(guī)則來計(jì)算。
如果F是程序不能并行運(yùn)行的百分比,N是進(jìn)程數(shù),則最大性能增益為1/(F+((1-F)/N))。
線程有自己的調(diào)用棧,但也可以訪問共享數(shù)據(jù)。因此,您有兩個(gè)基本問題,可見性和訪問問題。
如果線程A讀取后來由線程B更改的共享數(shù)據(jù)并且線程A不知道此更改,則會(huì)出現(xiàn)可見性問題。
如果多個(gè)線程同時(shí)訪問和更改相同的共享數(shù)據(jù),則可能會(huì)出現(xiàn)訪問問題。
可見性和訪問問題可能導(dǎo)致:
活躍度失?。河捎跀?shù)據(jù)并發(fā)訪問中的問題,例如死鎖,程序不再反應(yīng)。
安全故障:程序創(chuàng)建了不正確的數(shù)據(jù)。
Java程序在自己的進(jìn)程中運(yùn)行,默認(rèn)情況下在一個(gè)線程中運(yùn)行。Java通過代碼支持線程作為Java語言的一部分Thread。Java應(yīng)用程序可以通過此類創(chuàng)建新線程。
Java 1.5還為包的并發(fā)提供了改進(jìn)的支持java.util.concurrent。
Java提供了鎖來保護(hù)代碼的某些部分,以便同時(shí)由多個(gè)線程執(zhí)行。鎖定某個(gè)方法或Java類的最簡(jiǎn)單方法是使用synchronized關(guān)鍵字定義方法或類。
Java中的synchronized關(guān)鍵字確保:
只有一個(gè)線程可以同時(shí)執(zhí)行一段代碼
進(jìn)入同步代碼塊的每個(gè)線程都會(huì)看到由同一鎖保護(hù)的所有先前修改的效果
對(duì)于線程塊的互斥訪問和線程之間的可靠通信,同步是必需的。
您可以使用synchronized關(guān)鍵字來定義方法。這將確保只有一個(gè)線程可以同時(shí)進(jìn)入該方法。另一個(gè)調(diào)用這個(gè)方法的線程會(huì)一直等到第一個(gè)線程離開這個(gè)方法。
public synchronized void critial() {
// some thread critical stuff
// here
}
您還可以使用synchronized關(guān)鍵字來保護(hù)方法中的代碼塊。該塊由一個(gè)鍵保護(hù),該鍵可以是字符串或?qū)ο蟆_@把鑰匙叫做鎖。
所有受同一個(gè)鎖保護(hù)的代碼只能由一個(gè)線程同時(shí)執(zhí)行。
例如下面的數(shù)據(jù)結(jié)構(gòu)將確保只有一個(gè)線程可以訪問add()andnext()方法的內(nèi)部塊。
package de.vogella.pagerank.crawler;
import java.util.ArrayList;
import java.util.List;
/**
* Data structure for a web crawler. Keeps track of the visited sites and keeps
* a list of sites which needs still to be crawled.
*
* @author Lars Vogel
*
*/
public class CrawledSites {
private List<String> crawledSites = new ArrayList<String>();
private List<String> linkedSites = new ArrayList<String>();
public void add(String site) {
synchronized (this) {
if (!crawledSites.contains(site)) {
linkedSites.add(site);
}
}
}
/**
* Get next site to crawl. Can return null (if nothing to crawl)
*/
public String next() {
if (linkedSites.size() == 0) {
return null;
}
synchronized (this) {
// Need to check again if size has changed
if (linkedSites.size() > 0) {
String s = linkedSites.get(0);
linkedSites.remove(0);
crawledSites.add(s);
return s;
}
return null;
}
}
}
以上就是動(dòng)力節(jié)點(diǎn)小編介紹的"2022年Java并發(fā)-多線程的學(xué)習(xí)指南",希望對(duì)大家有幫助,如有疑問,請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為您服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)