不輟集

Java 多線程

首先區分進程和線程。進程是程序運行的基本單位,也是系統分配資源的最小單位;而線程是 CPU 調度的最小單位,一個進程可以有多個線程,而各個線程擁有獨立的程序計數器、虛擬機棧和本地方法棧,但共享同一個堆和方法區。爲著充分利用系統資源,減少 CPU 空等,多線程技術應運而生。系統使用時間片輪轉法分配 CPU 資源到各個線程,如果線程在分配的時間片內未能處理完任務,則會導致上下文切換。

Java 中線程類爲 Thread ,其 start 方法會使線程進入 Runnable 狀態;其 sleep 方法會阻塞線程而不釋放鎖,跟 Object.wait 有別;其 interrupt 方法並不停止線程,而是設置一個標誌位通知線程應當關閉,線程可以根據該標誌位決定是否要停止運行。

多個線程可以通過線程池進行統一管理,好處是還可以提前 Ready 好一些線程避免等待線程創建的時間損耗;還可以使用舊的線程,減少線程的頻繁創建和銷毀的資源損耗。線程池推薦直接使用 ThreadPoolExecutor 的構造方法去創建,以便設置合適的構造參數。調用 ThreadPoolExecutor.execute 可以將一個 Runnable 任務放入線程池處理; 調用ThreadPoolExecutor.submit 可以將一個 Callable 任務放入線程池處理,返回一個 Future 代表處理結果,後續通過調用 Future.get 獲取處理結果,其過程是阻塞的。

Java 1.5 開始提供AbstractQueuedSynchronizer,用於創建多線程訪問共享資源的同步器,其內部使用一個名爲 CLH 的 FIFO 的雙向隊列進行資源分配。其常見實現類有:ReentrantLockReadWriteLockCountDownLatch 。其中 ReadWriteLock 性能優於 ReentrantLock ,因爲兩個讀操作在 ReadWriteLock 中不互斥而在 ReentrantLock 中互斥。

Java 1.8 開始提供了 CompletableFuture ,其實現了 Future 接口,並提供了基於回調的函數式異步編程方式和對CompletableFuture 的組合,使用者可以不關心底層的線程池,大大簡便了異步編程。

Java 還提供了 ThreadLocal 類可以使得各個線程擁有變量的副本而不會相互影響,底層是使用 Thread 類的 ThreadLocalMap,一個類似 HashMap 的結構,其 Key 爲 ThreadLocal 對象的弱引用。

多線程因會有多個線程操作共享的資源而引發了線程安全的擔憂。線程安全要求原子性、可見性和有序性。Java 提供了多種方式可以保證線程安全:

  1. synchronized 同步鎖,這是一個重量級鎖。可以使用當前類的 class 對象,當前類的對象或者任意對象對方法和代碼塊進行加鎖,方法結束或代碼塊結束則鎖自動釋放。當使用非靜態同步方法時,會使用當前對象爲鎖,因此多個非靜態同步方法共享同一鎖。Java 1.6 後引入偏向鎖輕量級鎖的概念,使得 synchronized 不那麼「重」了。
  2. volatile 關鍵字。使用該關鍵字修飾的變量在編譯時不會有寄存器緩存而是直接使用主存、不會進行代碼重排序優化,保證了可見性和有序性;在解釋執行時使用 CPU 內存屏障技術防止指令重排序。
  3. CAS(Compare and Swap) 技術,相比於 synchronized,其假定操作是不會產生衝突的,將舊的預期值和內存中的值進行比較,若相同則更新內存中的值,否則自旋。因此被稱之爲「樂觀鎖」,而 synchronized 被稱之爲「悲觀鎖」。Java 中的 Atomic 類是典型的 CAS 實現。

多線程操作共享資源還會出現死鎖。死鎖產生的條件是:互斥、請求/等待、不可剝奪和循環等待。解決死鎖問題的關鍵是破壞死鎖產生的條件。

接續讀落

潮州話與甲子話韻母差異(稿)

概述

本文所說的潮州話指的是狹義的潮州話,即潮州市內通行的閩南語,甲子話則是指陸豐市甲子鎮內通行的閩南語。
通過比較,發現甲子話沒有潮州話中的 e、eh、eng、ou、iou、iouh、uê、uêh、uên、uêng、uêg、iê、iêh、iên、iêng、iêg 等韻,而與之相對應的是 u、uh、ng、ao、iao、iaoh、oi、oih、oin、uang、êng、iang、oig、io、ioh、ion、iang、iag 等等韻。

接續讀落

在潮劇中學之《玉堂春》

潮劇自明朝已然形成,發展到現在有近 500 年的歷史,據統計截止 2007 年 6 月已有超過 5000 個劇目。明朝嘉靖丙寅年(1566年)刊本的《荔鏡記》,是迄今所能見到的最早一個運用「泉潮腔」演唱的演出劇本。它於 2006 年被列入首批國家級非物質文化遺產保護名錄。

潮劇的語音特點是:最早的潮劇基本上是以潮州府城音爲主要音系來表演的,但迴避了潮州音的最明顯的特徵音韻母——潮州府城話的 iêng/iêg、uêng/uêg、iêm/iêb 等韻母,換成了跟其他方言相同的 iang/iag、uang/uag 和 iam/iab 韻母。然後,還參雜了揭陽話的一些特點。(引自林倫倫《潮劇是用哪個地方的方言來演唱的?》)

接續讀落

聆聽音樂:蕭邦之「雨滴」

我發現聆聽音樂在提高自身的音樂素養的同時還可以提高自己的想像力,進而提高記憶力,實在是一舉多得。從今往後,我要多多聆聽,多多分享有感覺的音樂吶。

今天點到蕭邦的「雨滴」,其全名爲 Prelude Op. 28 No. 15 Db major (Raindrop),網易雲音樂上又寫成 Prélude in D:Flat Major, Op. 28, No. 15,是同樣的(繼續讀下去就知道爲什麼),翻譯成中文就是:降 D 大調前奏曲, 作品28之15。先來與君共賞。

接續讀落

詩經·秦風‧蒹葭 (甲子話注音版)


        

蒹葭[1]蒼蒼[2],白露爲霜。所謂伊人,在水一方。溯洄[3]從之,道阻且長。溯游[4]從之,宛在水中央。[5]
giam¹ gia¹ cng¹ cng¹, bêh⁸ lao³ ui⁵ sng¹. so² ui³ i¹ ring⁵‚ do¹ zui² zêg⁸ hng¹. sog⁴ hoi⁵ ciong⁵ zu¹‚ dao⁶ zo² cian² dng⁵. sog⁴ iu⁵ ciong⁵ zu¹‚ uang² do¹ zui² dang¹ ng¹.

蒹葭萋萋,白露未晞[6]。所謂伊人,在水之湄[7]。溯洄從之,道阻且躋。溯游從之,宛在水中坻[8][9]
giam¹ gia¹ ci¹ ci¹‚ bêh⁸ lao³ bhoi⁷ hi¹. so² ui³ i¹ ring⁵‚ do¹ zui² zu¹ mi⁵. sog⁴ hoi⁵ ciong⁵ zu¹‚ dao⁶ zo² cian² zi³. sog⁴ iu⁵ ciong¹ zu¹‚ uang² do¹ zui² dang¹ di².

蒹葭采采,白露未已[10]。所謂伊人,在水之涘[11]。溯洄從之,道阻且右[12]。溯游從之,宛在水中沚[13][14]_ giam¹ gia¹ cai² cai²‚ bêh⁸ lao³ bhoi⁷ in². so² ui³ i¹ ring⁵‚ do¹ zui² zu¹ su⁶. sog⁴ hoi⁵ ciong⁵ zu¹‚ dao⁶ zo² cian² iu⁶. sog⁴ iu⁵ ciong¹ zu¹‚ uang² do¹ zui² dang¹ zi².

接續讀落