08 | 管程:併發編程的萬能鑰匙

併發編程這個技術領域已經發展了半個世紀了,相關的理論和技術紛繁複雜。那有沒有一種核心技術可以很方便地解決我們的併發問題呢?這個問題如果讓我選擇,我一定會選擇管程技術。Java 語言在 1.5 之前,提供的唯一的併發原語就是管程,而且 1.5 之後提供的 SDK 併發包,也是以管程技術爲基礎的。除此之外,C/C++、C# 等高級語言也都支持管程。可以這麼說,管程就是一把解決併發問題的萬能鑰匙。什麼是管程不知道你是否曾思考過這個問題:爲什麼 Java 在 1.5 之前僅僅提供了 synchronized 關鍵字及 wait()、notify()、notifyAll() 這三個看似從天而降的方法?在剛接觸 Java 的時候,我以爲它會提供信號量這種編程原語,因爲操作系統原理課程告訴我,用信號量能解決所有併發問題,結果我發現不是。後來我找到了原因:Java 採用的是管程技術,synchronized 關鍵字及 wait()、notify()、notifyAll() 這三個方法都是管程的組成部分。而管程和信號量是等價的,所謂等價指的是用管程能夠實現信號量,也能用信號量實現管程。但是管程更容易使用,所以 Java 選擇了管程。管程,對應的英文是 Monitor,很多 Java 領域的同學都喜歡將其翻譯成“監視器”,這是直譯。操作系統領域一般都翻譯成“管程”,這個是意譯,而我自己也更傾向於使用“管程”。所謂管程,指的是管理共享變量以及對共享變量的操作過程,讓他們支持併發。翻譯爲 Java 領域的語言,就是管理類的成員變量和成員方法,讓這個類是線程安全的。那管程是怎麼管的呢?MESA 模型在管程的發展史上,先後出現過三種不同的管程模型,分別是:Hasen 模型、Hoare 模型和 MESA 模型。其中,現在廣泛應用的是 MESA 模型,並且 Java 管程的實現參考的也是 MESA 模型。所以今天我們重點介紹一下 MESA 模型。在併發編程領域,有兩大核心問題:一個是互斥,即同一時刻只允許一個線程訪問共享資源;另一個是同步,即線程之間如何通信、協作。這兩大問題,管程都是能夠解決的。我們先來看看管程是如何解決互斥問題的。管程解決互斥問題的思路很簡單,就是將共享變量及其對共享變量的操作統一封裝起來。假如我們要實現一個線程安全的阻塞隊列,一個最直觀的想法就是:將線程不安全的隊列封裝起來,
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章