Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
What to Upload to SlideShare
Next
Download to read offline and view in fullscreen.

Share

CH11:執行緒與並行API

Download to read offline

認識Thread與Runnable
使用synchronized
使用wait()、notify()、notifyAll()
運用高階並行API

Related Books

Free with a 30 day trial from Scribd

See all
  • Be the first to like this

CH11:執行緒與並行API

  1. 1. 1
  2. 2. 執行緒與並行API 學習目標 • 認識Thread與Runnable • 使用synchronized • 使用wait()、notify()、 notifyAll() • 運用高階並行API 2
  3. 3. 簡介執行緒 3
  4. 4. • 實作java.lang.Runnable介面 4
  5. 5. 5
  6. 6. • 建構Thread實例來執行Runnable實例定義 的run()方法 6
  7. 7. Thread與Runnable • 定義Runnable的run()方法 • Thread類別,並重新定義run()方法 7
  8. 8. 8
  9. 9. • 實作Runnable較有彈性,因為類別還有機 會繼承其他類別 • 若繼承了Thread,那該類別就是一種 Thread 9
  10. 10. • 使用Lambda表示式 10
  11. 11. Daemon執行緒 • 主執行緒中啟動了其他執行緒,預設會等待 被啟動的執行緒都執行完 • 若有Thread被標示為Daemon執行緒,在非 Daemon執行緒都結束時,JVM就會終止 11
  12. 12. Thread基本狀態圖 12
  13. 13. • 運用多執行緒,當某執行緒進入Blocked時, 讓另一執行緒排入CPU執行(成為Running 狀態),避免CPU空閒下來,經常是改進效 能的方式之一 13
  14. 14. 14
  15. 15. 15
  16. 16. • 使用Thread.sleep()會讓執行緒進入 Blocked狀態 16
  17. 17. • join()表示將執行緒加入成為另一執行緒的 流程 • 可以在join()時指定時間 17
  18. 18. • 執行緒完成run()方法後,會進入Dead狀態 • 進入Dead(或已經呼叫過start()方法)的 執行緒不可呼叫start()方法,否則會拋出 IllegalThreadStateException • Thread類別定義了stop()方法,不過被標 示為Deprecated 18
  19. 19. 19
  20. 20. • 要停止執行緒,最好自行實作,讓執行緒跑 完應有的流程,而非呼叫Thread的stop() • 執行緒的暫停、重啟,也必須視需求實作, 而不是直接呼叫suspend()、resume()等20
  21. 21. 關於ThreadGroup • 執行緒都屬於某執行緒群組 • 在main()主流程中產生執行緒,該執行緒會 屬於main執行緒群組 21
  22. 22. • 若沒有指定,會歸入產生該子執行緒的執行 緒群組 • 執行緒一旦歸入某群組,就無法更換群組 22
  23. 23. • ThreadGroup的某些方法,可以對群組中 的執行緒產生作用 • 若想一次取得群組中全部的執行緒,可以使 用enumerate()方法 • activeCount()方法可取得群組的執行緒 數量 23
  24. 24. • uncaughtException()方法,群組中某個 執行緒發生例外而未捕捉時,JVM會呼叫此 方法進行處理 24
  25. 25. • 對於執行緒本身未捕捉的例外,自行指定處 理方式 25
  26. 26. synchronized與volatile • 若有兩個以上的執行緒 26
  27. 27. 27
  28. 28. • 競速情況(Race condition) • 執行緒安全(Thread-safe) 28
  29. 29. 使用synchronized • 若在方法標示synchronized,執行方法必 須取得該實例的內部鎖 29
  30. 30. 30
  31. 31. • synchronized不只可宣告在方法上,也可 作為陳述句使用 31
  32. 32. • 對於本身設計時沒有考慮競速問題的API來說 32
  33. 33. • Collections的 synchronizedCollection()、 synchronizedList()、 synchronizedSet()、 synchronizedMap()等方法 33
  34. 34. 34
  35. 35. 35
  36. 36. • synchronized提供的是可重入同步( Reentrant Synchronization) • 不正確地使用synchronized可能造成效能 低落,另一問題則是死結(Dead lock) – 你不放開resource1的內部鎖,我就不放開 resource2的內部鎖 36
  37. 37. 37
  38. 38. 38
  39. 39. 使用volatile • synchronized要求達到被標示區塊互斥性 (Mutual exclusion)與可見性(Visibility) – 互斥性是指synchronized區塊只允許一個執行 緒 – 可見性是指執行緒離開synchronized區塊後, 另一執行緒接觸到的就是上一執行緒改變後的物 件狀態 • 對於可見性的要求,可以使用volatile達 到變數範圍 39
  40. 40. 40
  41. 41. 41
  42. 42. 42
  43. 43. 43
  44. 44. • 為了效率,執行緒可以快取變數的值 • 可以在變數上宣告volatile,表示變數是 不穩定、易變的 – 也就是可能在多執行緒下存取,這保證變數的可 見性 – 若有執行緒變動了變數值,另一執行緒必然能看 到變更 • 被標示為volatile的變數,不允許執行緒 快取,變數值存取必須在共享記憶體中進行 44
  45. 45. 45
  46. 46. 46
  47. 47. • 正確使用volatile的例子: 47
  48. 48. 等待與通知 • wait()、notify()與notifyAll() 48
  49. 49. 49
  50. 50. 50
  51. 51. 51
  52. 52. 52
  53. 53. 53
  54. 54. 並行API • 使用Thread建立多執行緒程式,必須親自處 理細節 • 如果需要的是執行緒池、讀寫鎖等高階操作 – java.util.concurrent套件 54
  55. 55. 使用Lock • ReentrantLock可以達到synchronized 的作用,也提供了額外功能 55
  56. 56. 56
  57. 57. • Lock介面還定義了tryLock()方法 57
  58. 58. 58
  59. 59. 59
  60. 60. 使用ReadWriteLock • 定義了讀取鎖定與寫入鎖定行為 • readLock()、writeLock()方法 – ReentrantReadWriteLock.ReadLock沒有 任何寫入鎖定時,才可以取得讀取鎖定 – ReentrantReadWriteLock.WriteLock沒有 任何讀取或寫入鎖定時,才可以取得寫入鎖 60
  61. 61. 61
  62. 62. 62
  63. 63. 使用StampedLock • ReadWriteLock在沒有任何讀取或寫入鎖 定時,才可以取得寫入鎖定,這可用於實現 悲觀讀取(Pessimistic Reading) – 飢餓(Starvation)問題 • StampedLock類別可支援樂觀讀取( Optimistic Reading) 63
  64. 64. 64
  65. 65. 65
  66. 66. 使用Condition • 用來搭配Lock 66
  67. 67. 67
  68. 68. • 使用了一個Condition,就有一個等待集 68
  69. 69. 69
  70. 70. 使用Executor • 將Runnable的指定與執行分離 70
  71. 71. 71
  72. 72. 72
  73. 73. • 若定義一個ThreadPerTaskExecutor: 73
  74. 74. 74
  75. 75. 使用ThreadPoolExecutor • 執行緒池這類服務的行為,定義在 Executor的子介面ExecutorService • 根據不同的執行緒池需求, ThreadPoolExecutor擁有數種不同建構 式可供使用 75
  76. 76. • 通常會使用Executors的 newCachedThreadPool()、 newFixedThreadPool()靜態方法來建構 76
  77. 77. • ExecutorService還定義了submit()、 invokeAll()、invokeAny()等方法 • 這些方法中出現了 java.util.concurrent.Future、 java.util.concurrent.Callable介面 77
  78. 78. • Future定義的行為,就是在未來取得結果 • 經常與Callable搭配使用 • FutureTask是Future的實作類別 78
  79. 79. 79
  80. 80. • ExecutorService的submit()方法,它 可以接受Callable物件 • 呼叫後傳回Future物件 80
  81. 81. ScheduledThreadPoolExecutor • 重複性的執行,可使用 scheduleWithFixedDelay()與 scheduleAtFixedRate()方法 81
  82. 82. 使用ForkJoinPool • 解決分而治之(Divide and conquer )的問題 82
  83. 83. 83
  84. 84. • ForkJoinPool實現了工作竊取演算 • ForkJoin框架適用於計算密集式的任務 84
  85. 85. 簡介並行Collection 85
  86. 86. • CopyOnWriteArrayList • CopyOnWriteArraySet • BlockingQueue • ConcurrentMap 86
  87. 87. 87
  88. 88. 88
  89. 89. 89

認識Thread與Runnable 使用synchronized 使用wait()、notify()、notifyAll() 運用高階並行API

Views

Total views

221

On Slideshare

0

From embeds

0

Number of embeds

0

Actions

Downloads

28

Shares

0

Comments

0

Likes

0

×