溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解java并發編程的三個核心問題

發布時間:2021-11-16 16:06:14 來源:億速云 閱讀:144 作者:iii 欄目:大數據

本篇內容主要講解“怎么理解java并發編程的三個核心問題”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“怎么理解java并發編程的三個核心問題”吧!

    總的來說,并發編程可以總結為三個核心問題:分工、同步、互斥。

    所謂分工指的是如何高效地拆解任務并分配給線程,而同步指的是線程之間如何協作,互斥則是保證同一時刻只允許一個線程訪問共享資源。java SDK并發包很大部分內容都是按照這三個維度組織的,例如Fork/Join框架就是一種分工模式,CountDownLatch就是一種典型的同步方式,而可重入鎖則是一種互斥手段。

    1.分工

    所謂分工,類似于現實中一個組織完成一個項目,項目經理要拆分任務,安排合適的成員去完成。

    在并發編程領域,你就是項目經理,線程就是項目組成員。任務分解和分工對于項目成敗非常關鍵,不過在并發領域里,分工更重要,它直接決定了并發程序的性能。在現實世界里,分工是很復雜的,著名數學家華羅庚曾用“燒水泡茶”的例子通俗地講解了統籌方法(一種安排工作進程的數學方法),“燒水泡茶”這么簡單的事情都這么多說道,更何況是并發編程里的工程問題呢。

    既然分工很重要又很復雜,那一定有前輩努力嘗試解決過,并且也一定有成果。的確,在并發編程領域這方面的成果還是很豐碩的。Java SDK并發包里的Executor、Fork/Join、Future本質上就是一種分工方法。除此之外,并發編程領域還總結了一些設計模式,基本上都是和分工方法相關的,例如生產者-消費者、Thread-Per-Message、Worker Thread模式等都是用來指導你如何分工的。

    了解這部分內容,最佳的方式就是和現實世界做對比。例如生產者-消費者模式,可以類比一下餐館里的大廚和服務員,大廚就是生產者,負責做菜,做完放到出菜口,而服務員就是消費者,把做好的菜給你端過來。不過,我們經常會發現,出菜口有時候一下子出了好幾個菜,服務員是可以吧這一批菜同時端給你的。其實這就是生產者-消費者模式的一個優點,生產者一個一個地生產數據,而消費者可以批處理,這樣就提高了性能。

    2.同步

    分好工之后,就是具體執行了。在項目執行過程中,任務之間是有依賴的,一個任務結束后,依賴它的后續任務任務就可以開工了,后續工作怎么知道可以開工了呢?這個就是靠溝通協作了,這是一項很重要的工作。

    在并發編程領域里的同步,主要指的就是線程間的協作,本質上和現實生活中的協作沒區別,不過是一個線程執行完了一個任務,如何通知執行后續任務的線程開工而已。協作一般是和分工相關的。Java SDK并發包里的Executor、Fork/Join、Future本質上都是分工方法,但同時也能解決線程協作的問題。例如,用Future可以發起一個異步調用,當主線程通過get()方法取結果時,主線程就會等待,當異步執行的結果返回時,get()方法就自動返回了。主線程和異步線程之間的協作,Future工具類已經幫我們解決了。除此之外,Java SDK里提供的CountDownLatch、CyclicBarrier、Phaser、Exchanger也都是用來解決線程協作的問題。

    不過還有很多場景,是需要你自己來處理線程之間的協作的。

    工作中遇到的線程協作的問題,基本上都可以描述為這樣的一個問題:當某個條件不滿足時,線程需要等待,當某個條件滿足時,線程需要被喚醒執行。例如,在生產者-消費者模型里,也有類似的描述,“當隊列滿時,生產者線程等待,當隊列不滿時,生產者線程需要被喚醒執行;當隊列空時,消費者線程等待,當隊列不為空時,消費者線程需要被喚醒執行?!?/p>

    在Java并發編程領域,解決協作問題的核心技術是管程,上面提到的所有線程協作技術底層都是利用管程解決的。管程是一種解決并發問題的通用模型,除了能解決線程協作問題,還能解決下面我們將要介紹的互斥問題??梢赃@么說,管程是解決并發問題的萬能鑰匙。

    所以說,這部分內容的學習,關鍵是理解管程模型,學好它就可以解決所有問題。其次,了解Java SDK并發包提供的幾個線程協作的工具類的應用場景,用好它們可以妥妥地提高你的工作效率。

    3.互斥

    分工、同步主要強調的是性能,但并發程序里還有一部分是關于正確性的,用專業術語叫“線程安全”。并發程序里,當多個線程同時訪問一個共享變量時,結果時不確定的。不確定,則意味著可能正確,也可能錯誤,事先是不知道的。而導致不確定的主要源頭是可見性的問題、有序性問題和原子性問題,為了解決這三個問題,Java語言引入了內存模型,內存模型提供了一系列的規則,利用這些規則,我們可以避免可見性問題、有序性問題,但是還不足以完全解決線程安全問題。解決線程安全問題的核心方案還是互斥。

    所謂互斥,指的是同一時刻,只允許一個線程訪問共享變量。

    實現互斥的核心技術就是鎖,Java語言里synchronized、SDK里的各種Lock都能解決互斥問題。雖說鎖解決了安全性問題,但同時也帶來了性能問題,那如何保證安全性的同時又盡量提高性能呢?可以分場景優化,Java SDK里提供的ReadWriteLock、StampedLock就可以優化讀多寫少場景下鎖的性能。還可以使用無鎖的數據結構,例如Java SDK里提供的原子類都是基于無鎖技術實現的。

    除此之外,還有一些其他的方案,原理是不共享變量或者變量只允許讀。這方面,Java 提供了Thread Local和final關鍵字,還有一種copy-on-write的模式。

    使用鎖除了要注意性能問題外,還需要注意死鎖問題。

    這部分內容比較復雜,往往還是跨領域的,例如要理解可見性,就需要了解一些CPU和緩存的知識;要理解原子性,就需要理解一些操作系統的知識;很多無鎖算法的實現往往也需要理解CPU緩存。這部分內容,需要博覽群書,在大腦里建立起CPU、內存、I/O執行的模擬器。這樣遇到問題就能得心應手了。

到此,相信大家對“怎么理解java并發編程的三個核心問題”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女