最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java線程之間的共享與協(xié)作詳解

 更新時間:2022年07月01日 14:40:41   作者:半身風雪  
這篇文章主要介紹了Java線程之間的共享與協(xié)作詳解,進程是操作系統(tǒng)進行資源分配的最小單位,線程是進程的一個實體,是CPU調度和分派的基本單位,它是比經常更小的、能夠獨立運行的基本單位

前言

在系列文章開始之前,我們首先了解一下線程的重要性: ??線程??(Thread)是“進程”中某個單一順序的控制流。也被稱為輕量進程(lightweight

processes)。計算機科學術語,指運行中的程序的調度單位。

所有的程序中,都有線程

一、進程和線程

1、進程是程序運行資源分配的最小單位

進程是操作系統(tǒng)進行資源分配的最小單位,其中包括:CPU、內存空間、磁盤IO 等、同一進程中的多條線程共享該進程中的全部系統(tǒng)資源,而進程和進程直接是相互獨立的。進程是具有一定獨立功能的程序關于某個數據集合上的一次運行活動,進程是系統(tǒng)進行資源分配和調度的一個獨立單位。

進程是程序在計算機上的一次執(zhí)行活動。當你運行一個程序,你就啟動了一個進程。顯然程序是死的、靜態(tài)的、進程是活動的、動態(tài)的。進程可以分為系統(tǒng)進程和用戶進程。凡是用于完成操作系統(tǒng)的各種功能的進程就是系統(tǒng)進程,它們是處于運行狀態(tài)下的操作系統(tǒng)本身,用戶進程就是所有由你啟動的進程。

2、線程是CPU 調度的最小單位,必須依賴于進程而存在

線程是進程的一個實體,是CPU調度和分派的基本單位,它是比經常更小的、能夠獨立運行的基本單位。線程自己基本上不擁有系統(tǒng)資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和堆棧),但是它可以與同一個進程的其他線程共享進程所擁有的全部資源。

3、線程無處不在

任何一個程序都必須創(chuàng)建線程,特別是Java不管任何程序都必須啟動一個main函數的主線程;Java web開發(fā)的定時任務、定時器、JSPServlet、異步消息處理機制,遠程訪問接口 RM 等,任何一個監(jiān)聽事件,onClick的觸發(fā)事件等都離不開線程和并發(fā)的知識。

二、CPU 核心數和線程數的關系

1、多核心

多核心:也指單芯片多處理器(Chip Multiprocessors,簡稱 CMP),CMP是由美國斯坦福大學提出的,其思想是將大規(guī)模并行處理器中的SMP(對稱處理器)集成到同一芯片內,各個處理器并行執(zhí)行不同的進程。這種依靠多個CPU同時并行的運行程序是實現(xiàn)超高速計算的一個重要方向,稱為并行處理。

2、多線程

多線程Simultaneous Multithreading.簡稱 SMT.讓同一個處理器上的多個線程同步執(zhí)行并共享處理器的執(zhí)行資源。

3、核心數、線程數

核心數、線程數:目前主流CPU都是多核的。增加核心數目的就是為了增加線程數,因為操作系統(tǒng)是通過線程來執(zhí)行任務的,一般情況下它們是1:1對應關系,也就是說四核 CPU一般擁有四個線程。但Intel引入超線程技術后,使核心數與線程數形成了1:2的關系。

三、CPU 時間片輪轉機制

我們平時在開發(fā)的時候,感覺并沒有受CPU 核心數的限制,想啟動線程就啟動線程,哪怕是在單核CPU 上,為什么?這是因為操作系統(tǒng)提供了一種CPU 時間片輪轉機制。

時間片輪轉調度是一種最古老、最簡單、最公平且使用最廣的一種算法,又稱RR 調度。每個進程被分配一個時間段,稱作它的時間片,即該進程運行運行的時間。

四、并行和并發(fā)

我們舉個例子,如果有條高速公路A,上面有4條車道,那么最大并行車輛就是4輛,這條高速公路同時并排行走的車輛小與等于4的時候,車輛就可以并行行駛。CPU也是這個原理,一個CPU相當于一條高速公路,核心數或線程數就相當于并排可以通行的車輛;而多個CPU就相當于有多條高速公路,而每個高速公路并排有多個車道。

當談論并發(fā)的時候,一定要加個單位時間,也就是說單位時間內并發(fā)量是多少?離開單位時間其實是沒有意義的。

俗話說一心不能二用,這對計算機也一樣,原則上一個CPU只能分配給一個進程,以便運行這個進程。我們通常用的計算機只有一個CPU,也就是說只有一顆心,要讓它一心多用同時運行多個進程,就必須使用并發(fā)技術。實現(xiàn)并發(fā)技術相當復雜,最容易理解的是“時間片輪轉進程調度算法”。

1、并發(fā)

并發(fā):指應用能夠交替執(zhí)行不同的任務,比如單CPU核心下執(zhí)行多線程并非是同時執(zhí)行多個任何,如果你開兩個線程執(zhí)行,就是在你幾乎不可察覺的速度不斷去切換執(zhí)行這兩個任務,以達到“同時執(zhí)行”效果,只是計算機的執(zhí)行速度太快,我們無法察覺到而已。

2、并行

并行:指應用能夠同時執(zhí)行不同的任務,例:吃飯的時候可以邊吃飯邊看電視,這兩件事可以同時執(zhí)行。

**并發(fā)和并行兩者的區(qū)別就是:一個是交替執(zhí)行,一個是同時執(zhí)行**

五、高并發(fā)編程

由于多核CPU的誕生,多線程、高并發(fā)的編程越來越受重視和關注。

1、CPU 資源利用的充分

從上面CPU的介紹,可以看出現(xiàn)在市面上沒有CPU的內核不使用多線程并發(fā)機制的,特別是服務器還不止一個CPU。程序的基本調度單元是線程,一個線程也只能在一個一個CPU 的一個核的一個線程跑,如果你是個i3的CPU的話,最差也是雙核心4線程的運算能力:如果是一個線程的話,那就會浪費釣3/4的CPU性能:如果設計一個多線程的話,那它就可以同時在多個CPU 的多個核的多個線程上跑,可以充分的利用CPU,減少CPU的空閑時間,發(fā)揮它的運算能力,提高并發(fā)量。

2、加快用戶響應時間

比如我們經常使用的下載功能,很多朋友都會開通某一個會員,因為會員版本啟用了多個線程去下載,誰都無法忍受一個線程去下,為什么呢?因為多線程下載快啊。

我們做程序開發(fā)的時候,網頁速度提升1s,如果用戶量大的話,就能增加不少轉換量。我們經常瀏覽的網頁中,瀏覽器在加載頁面的時候,都會去多開幾個線程去加載網絡資源,提升網站的相應速度。多線程和高并發(fā),在計算機中,無處不在。

3、使代碼模塊化、異步化、簡單化

例如我們做一個電商項目,下訂單和給用戶發(fā)送短信、郵件就可以進行拆分,將給用戶發(fā)送短信、郵件這兩個步驟獨立成兩個單獨的模塊,交給其他線程去執(zhí)行。這樣即增加了異步的操作,提示了系統(tǒng)性能,又使程序模塊化,清晰化和簡單化。

六、多線程注意事項

1、線程之間的安全性

從前面的章節(jié)中我們都知道了,在同一個進程里面的多線程是資源共享的,也就是都可以訪問同一個內存地址當中的一個變量。

例如:若每個線程中對全局變量、靜態(tài)變量只讀操作,而無寫操作,一般來說,這個全局變量是線程安全的;若有多個線程同時執(zhí)行寫操作,一般都需要考慮線程同步,否則就可能影響線程安全。

2、線程之間的死鎖

為了解決線程之間的安全性引入了Java 鎖的機制,而一不小心就會產生Java 線程死鎖的多線程問題,因為不同的線程都在等待哪些根本不可能被釋放的鎖,從而導致所有的工作都無法完成。

假設有兩個饑餓的人,他們必須共享刀叉并輪流吃飯,他們都需要獲得兩個鎖,共享刀和共享叉。假如線程A獲得了刀,而線程B獲得了叉。線程A就會進入阻塞狀態(tài)來等待獲得叉,而線程B則主帥來等待線程A所擁有的刀。這只是人為設計的例子,單盡管在運行時很難探測到,這類情況卻時常發(fā)生。

3、線程多了會將服務資源耗盡形成死機、當機

線程數太多有可能造成系統(tǒng)創(chuàng)建大量線程,而導致消耗完系統(tǒng)內存以及CPU的“過渡切換”,造成系統(tǒng)的死機,那么我們改如果解決這類問題呢?

某些系統(tǒng)資源是有限的,如文件描述。多線程程序可能耗盡資源,因為每個線程都可能希望有一個這樣的資源。如果線程數相當大,或者某個資源的侯選線 程數遠遠超過了可用的資源數則最好使用資源池。一個最好的示例是數據庫連接池。只要線程需要使用一個數據庫連接,它就從池中取出一個,使用以后再將它返回池中。資源池也稱為資源庫。

多線程應用開發(fā)的注意事項很多,希望大家在日后的工作中可以慢慢體會它 的危險所在。

七、多線程注意事項

線程之間相互配合,完成某項工作,比如:一個線程修改了一個對象的值, 而另一個線程感知到了變化,然后進行相應的操作,整個過程開始于一個線程, 而最終執(zhí)行又是另一個線程。前者是生產者,后者就是消費者,這種模式隔離了 “做什么”(what)和“怎么做”(How),簡單的辦法是讓消費者線程不斷地 循環(huán)檢查變量是否符合預期在 while 循環(huán)中設置不滿足的條件,如果條件滿足則 退出 while 循環(huán),從而完成消費者的工作。

卻存在如下問題:

  • 難以確保及時性。
  • 難以降低開銷。如果降低睡眠的時間,比如休眠 1 毫秒,這樣消費者能 更加迅速地發(fā)現(xiàn)條件變化,但是卻可能消耗更多的處理器資源,造成了無端的浪費。

等待/通知機制:是指一個線程 A 調用了對象 O 的 wait()方法進入等待狀態(tài),而另一個線程 B 調用了對象 O 的 notify()或者 notifyAll()方法,線程 A 收到通知后從對象 O 的 wait() 方法返回,進而執(zhí)行后續(xù)操作。上述兩個線程通過對象 O 來完成交互,而對象 上的 wait()和 notify/notifyAll()的關系就如同開關信號一樣,用來完成等待方和通 知方之間的交互工作。

notify():通知一個在對象上等待的線程,使其從 wait 方法返回,而返回的前提是該線程獲取到了對象的鎖,沒有獲得鎖的線程重新進入 WAITING 狀態(tài)。

notifyAll():通知所有等待在該對象上的線程

wait():調用該方法的線程進入 WAITING 狀態(tài),只有等待另外線程的通知或被中斷 才會返回.需要注意,調用 wait()方法后,會釋放對象的鎖。

wait(long):超時等待一段時間,這里的參數時間是毫秒,也就是等待長達n 毫秒,如果沒有 通知就超時返回。

wait (long,int):對于超時時間更細粒度的控制,可以達到納秒

等待和通知的標準范式 等待方遵循如下原則。

  • 獲取對象的鎖。
  • 如果條件不滿足,那么調用對象的 wait()方法,被通知后仍要檢查條件。
  • 條件滿足則執(zhí)行對應的邏輯。

通知方遵循如下原則:

  • 獲得對象的鎖。
  • 改變條件。
  • 通知所有等待在對象上的線程。

??在調用 wait()、notify()系列方法之前,線程必須要獲得該對象的對象級別鎖,即只能在同步方法或同步塊中調用 wait()方法、notify()系列方法,進 入 wait()方法后,當前線程釋放鎖,在從 wait()返回前,線程與其他線程競 爭重新獲得鎖,執(zhí)行 notify()系列方法的線程退出調用了 notifyAll 的 synchronized 代碼塊的時候后,他們就會去競爭。如果其中一個線程獲得了該對象鎖,它就會 繼續(xù)往下執(zhí)行,在它退出 synchronized 代碼塊,釋放鎖后,其他的已經被喚醒的 線程將會繼續(xù)競爭獲取該鎖,一直進行下去,直到所有被喚醒的線程都執(zhí)行完畢。

notify 和 notifyAll 應該用誰

盡可能用 notifyAll(),謹慎使用 notify(),因為 notify()只會喚醒一個線程,我們無法確保被喚醒的這個線程一定就是我們需要喚醒的線程。

到此這篇關于Java線程之間的共享與協(xié)作詳解的文章就介紹到這了,更多相關Java線程共享與協(xié)作內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論

宁南县| 汨罗市| 汝城县| 临潭县| 宁化县| 青岛市| 米林县| 崇信县| 含山县| 德阳市| 陕西省| 淳化县| 盐边县| 阜城县| 义马市| 涡阳县| 得荣县| 栾川县| 舟山市| 平定县| 洪洞县| 河北省| 同德县| 台山市| 东宁县| 新乐市| 桂林市| 鄱阳县| 五峰| 西昌市| 惠东县| 林口县| 苗栗市| 斗六市| 儋州市| 乐安县| 大连市| 沙坪坝区| 大荔县| 怀化市| 藁城市|