日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
從零開始學(xué)Java有關(guān)線程的學(xué)習(xí)總結(jié)

《Java編程思想》整理的一些學(xué)習(xí)筆記,有不對的地方,歡迎指出。

1 .資源沖突,如果兩個線程確實(shí)是在修改同一個對象,共享資源的沖突將變得更糟糕,因?yàn)檫@有可能把對象設(shè)置成不正確的狀態(tài)。通過簡單的“信號量”概念引入, 把它看作是在兩個線程之間進(jìn)行通信的標(biāo)志對象。如果信號量的值是零,則它監(jiān)控的資源是可用的,但如果這個值是非零的,則被監(jiān)控的資源不可用,所以線程必須 等待。當(dāng)資源可用的時候,線程增加信號量的值,然后繼續(xù)執(zhí)行這個被監(jiān)控的資源。把增加和減少信號量的操作定義為原子操作,這樣就可保證兩個線程同時訪問同 一資源的時候不至于沖突。 
定義一個簡化的信號量:

  
 
  1. class="hljs java has-numbering" style="display: block; padding: 0px; 
  2. color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', 
  3. monospace;font-size:undefined; white-space: pre; border-top-left-radius: 
  4. 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; 
  5. border-bottom-left-radius: 0px; word-wrap: normal; background: 
  6. transparent;">
  7. 136); box-sizing: border-box;">public 
  8. class="hljs-class" style="box-sizing: border-box;">
  9. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  10. border-box;">class 
  11. style="box-sizing: border-box; color: rgb(102, 0, 
  12. 102);">Semaphore 
  13. style="color: rgb(0, 0, 136); box-sizing: 
  14. border-box;">implements 
  15. style="box-sizing: border-box; color: rgb(102, 0, 
  16. 102);">Invariant{ 
  17.     
  18. box-sizing: border-box;">private 
  19. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  20. border-box;">volatile 
  21. style="color: rgb(0, 0, 136); box-sizing: 
  22. border-box;">int semaphore = 
  23. class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
  24. border-box;">0; 
  25.     
  26. box-sizing: border-box;">public 
  27. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  28. border-box;">boolean 
  29. style="box-sizing: border-box;">available(){
  30. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  31. border-box;">return semaphore==
  32. class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
  33. border-box;">0;} 
  34.     
  35. box-sizing: border-box;">public 
  36. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  37. border-box;">void 
  38. style="box-sizing: border-box;">acquire(){ ++semaphore; } 
  39.     
  40. box-sizing: border-box;">public 
  41. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  42. border-box;">void 
  43. style="box-sizing: border-box;">release(){ --semaphore; } 
  44.     
  45. box-sizing: border-box;">public InvariantSate 
  46. class="hljs-title" style="box-sizing: 
  47. border-box;">invariant(){ 
  48.         
  49. box-sizing: border-box;">int val = semaphore; 
  50.         
  51. box-sizing: border-box;">if( val==
  52. class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: 
  53. border-box;">0||val==
  54. style="color: rgb(0, 102, 102); box-sizing: 
  55. border-box;">1 ) 
  56.             
  57. box-sizing: border-box;">return 
  58. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  59. border-box;">new InvariantOk(); 
  60.         
  61. box-sizing: border-box;">else 
  62.             
  63. box-sizing: border-box;">return 
  64. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  65. border-box;">new InvariantFailure(
  66. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  67. border-box;">new Integer(val)); 
  68.     } 
  69. }
  70. border-box; position: absolute; width: 50px; top: 0px; left: 0px; 
  71. margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; 
  72. border-right-style: solid; border-right-color: rgb(221, 221, 221); 
  73. list-style: none; text-align: right; background-color: rgb(238, 238, 
  74. 238);">
  75. 5px;">1
  76. 5px;">2
  77. 5px;">3
  78. 5px;">4
  79. 5px;">5
  80. 5px;">6
  81. 5px;">7
  82. 5px;">8
  83. 5px;">9
  84. 5px;">10
  85. 5px;">11
  86. 0px 5px;">12
  87. 0px 5px;">13
  88.  

(其中Invariant接口在博客:線程測試框架已給出)將semaphore字段設(shè)置為volatile ,以確保編譯器不會對任何讀取此值的操作進(jìn)行優(yōu)化。

2.解決共享資源競爭,之前說過,可以通過yield()和setPriority()來給線程調(diào)度機(jī)制提供建議,但這些建議未必會有多大的效果,這取決 與你的具體平臺和JVM實(shí)現(xiàn)。Java以提供關(guān)鍵字 synchronized 的形式,為防止資源沖突提供了內(nèi)置支持。共享資源一般是以對象的形式存在的內(nèi)存判斷,但也可以是文件,輸入/輸出端口,或者是打印機(jī)。要控制對共享資源的 訪問,得先把它包裝進(jìn)一個對象。然后把所有要訪問這個資源的方法標(biāo)記為synchronized。即一旦某個線程處于一個標(biāo)記為synchronized 的方法中,那么在這個線程從該方法返回之前,其他所有要調(diào)用類中任何標(biāo)記為synchronized方法的線程都會被阻塞。 
每個對象都含有單一的鎖(也稱為監(jiān)視器),這個鎖本身就是對象的一部分(不用寫任何特殊代碼)。當(dāng)在對象上調(diào)用其任意synchronized方法的時 候,此對象都被加鎖,這時該對象上的其他synchronized方法也只能等到前一個方法調(diào)用完并釋放了鎖之后才能被調(diào)用。 
針對每一個類也有一個鎖(作為類的Class對象的一部分),所以synchronized static 方法可以在類的范圍內(nèi)防止對static數(shù)據(jù)的并發(fā)訪問。

3.原子操作,即不能被線程調(diào)度機(jī)制中斷的操作;一旦操作開始,那么它一定可以在可能發(fā)生的“上下文切換”之前(切換到其他線程執(zhí)行)執(zhí)行完畢。如果問題 中的變量類型是除long或double以外的基本類型,對這種變量進(jìn)行簡單的賦值或返回值操作的時候,才算是原子操作。然而,只要給long或 double加上volatile,操作就是原子的了。注意,在JVM中的自增加操作并不是原子操作,它牽涉到一次讀和一次寫,所以即使在這樣的簡單操作 中,也為線程出問題提供了空間。線程工作時,每個線程都可能擁有一個本地棧來維護(hù)一些變量的復(fù)本,如果把一個變量定義成volatile的,就等于告訴編 譯器不要做任何優(yōu)化,直接在主存操作變量。

4.保證上述問題解決,做安全的做法就是使用下面的方法: 
1)如果要對類中的某個方法進(jìn)行同步控制,***同步所有方法。如果忽略了其中一個,通常很難確定這么做是否會有負(fù)面影響。 
2)當(dāng)去除方法的同步控制時,要非常小心。通常這么做是基于性能方面的考慮,但在JDK1.3和JDK1.4中,同步控制所需的負(fù)擔(dān)已經(jīng)大大的減少。此外,只應(yīng)在使用性能評價(jià)工具證實(shí)了同步控制確實(shí)是性能瓶頸的時候,才這么做。

5.如果只是希望防止多個線程同時訪問方法內(nèi)部的部分代碼而不是防止整個方法,可以使用synchronized關(guān)鍵字來分離代碼段,這種方式被稱為“臨界區(qū)”,此時,synchronized被用來指定某個對象,此對象的鎖被用來對花括號內(nèi)的代碼進(jìn)行同步控制:

  
 
  1. class="hljs java has-numbering" style="display: block; padding: 0px; 
  2. color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', 
  3. monospace;font-size:undefined; white-space: pre; border-top-left-radius: 
  4. 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; 
  5. border-bottom-left-radius: 0px; word-wrap: normal; background: 
  6. transparent;">        
  7. rgb(0, 0, 136); box-sizing: 
  8. border-box;">synchronized(syncObject){ 
  9.             
  10. box-sizing: border-box;">// This code can be accessed 
  11.             
  12. box-sizing: border-box;">//by only one thread at a time 
  13.         }
  14. border-box; position: absolute; width: 50px; top: 0px; left: 0px; 
  15. margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; 
  16. border-right-style: solid; border-right-color: rgb(221, 221, 221); 
  17. list-style: none; text-align: right; background-color: rgb(238, 238, 
  18. 238);">
  19. 5px;">1
  20. 5px;">2
  21. 5px;">3
  22. 5px;">4
  23.  

使用同步控制塊,而不是對整個方法進(jìn)行同步控制,可以使多個線程訪問對象的時間性能得到顯著的提高。要注意的是,當(dāng)對象中的方法在不同的鎖上同步的時候,兩個線程可以訪問同一個對象:

  
 
  1. class="hljs cs has-numbering" style="display: block; padding: 0px; 
  2. color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', 
  3. monospace;font-size:undefined; white-space: pre; border-top-left-radius: 
  4. 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; 
  5. border-bottom-left-radius: 0px; word-wrap: normal; background: 
  6. transparent;">class DualSynch { 
  7.  
  8.     
  9. box-sizing: border-box;">private Object syncObject = 
  10. border-box;">new Object(); 
  11.  
  12.     
  13. box-sizing: border-box;">public synchronized 
  14. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  15. border-box;">void 
  16. style="box-sizing: border-box;">f() { 
  17.         System.
  18. 136); box-sizing: border-box;">out.println(
  19. class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: 
  20. border-box;">"Inside f()"); 
  21.         
  22. box-sizing: border-box;">try { 
  23.             Thread.sleep(
  24. rgb(0, 102, 102); box-sizing: border-box;">500); 
  25.         } 
  26. box-sizing: border-box;">catch (InterruptedException e) { 
  27.             
  28. box-sizing: border-box;">throw 
  29. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  30. border-box;">new RuntimeException(e); 
  31.         } 
  32.         System.
  33. 136); box-sizing: border-box;">out.println(
  34. class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: 
  35. border-box;">"leaving f()"); 
  36.     } 
  37.  
  38.     
  39. box-sizing: border-box;">public 
  40. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  41. border-box;">void 
  42. style="box-sizing: border-box;">g() { 
  43.  
  44.         synchronized (syncObject) { 
  45.             System.
  46. 136); box-sizing: border-box;">out.println(
  47. class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: 
  48. border-box;">"Inside g()"); 
  49.             
  50. box-sizing: border-box;">try { 
  51.                 Thread.sleep(
  52. rgb(0, 102, 102); box-sizing: border-box;">500); 
  53.             } 
  54. 136); box-sizing: border-box;">catch 
  55. (InterruptedException e) { 
  56.                 
  57. 136); box-sizing: border-box;">throw 
  58. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  59. border-box;">new RuntimeException(e); 
  60.             } 
  61.             System.
  62. 136); box-sizing: border-box;">out.println(
  63. class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: 
  64. border-box;">"leaving g()"); 
  65.         } 
  66.     } 
  67.  
  68. border-box;">public 
  69. style="color: rgb(0, 0, 136); box-sizing: 
  70. border-box;">class SyncObject{ 
  71.  
  72.     
  73. box-sizing: border-box;">public 
  74. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  75. border-box;">static 
  76. style="color: rgb(0, 0, 136); box-sizing: 
  77. border-box;">void 
  78. style="box-sizing: border-box;">main(String[] args){ 
  79.         final DualSynch ds = 
  80. rgb(0, 0, 136); box-sizing: border-box;">new 
  81. DualSynch(); 
  82.  
  83.         
  84. box-sizing: border-box;">new Thread(){ 
  85.             
  86. box-sizing: border-box;">public 
  87. class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: 
  88. border-box;">void 
  89. style="box-sizing: border-box;">run(){ 
  90.                 ds.f(); 
  91.             } 
  92.         }.start();; 
  93.  
  94.         ds.g(); 
  95.     } 
  96. }
  97. border-box; position: absolute; width: 50px; top: 0px; left: 0px; 
  98. margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; 
  99. border-right-style: solid; border-right-color: rgb(221, 221, 221); 
  100. list-style: none; text-align: right; background-color: rgb(238, 238, 
  101. 238);">
  102. 5px;">1
  103. 5px;">2
  104. 5px;">3
  105. 5px;">4
  106. 5px;">5
  107. 5px;">6
  108. 5px;">7
  109. 5px;">8
  110. 5px;">9
  111. 5px;">10
  112. 5px;">11
  113. 0px 5px;">12
  114. 0px 5px;">13
  115. padding: 0px 5px;">14
  116. padding: 0px 5px;">15
  117. border-box; padding: 0px 5px;">16
  118. border-box; padding: 0px 5px;">17
  119. style="box-sizing: border-box; padding: 0px 5px;">18
  120. style="box-sizing: border-box; padding: 0px 
  121. 5px;">19
  122. 5px;">20
  123. 0px 5px;">21
  124. 0px 5px;">22
  125. padding: 0px 5px;">23
  126. padding: 0px 5px;">24
  127. border-box; padding: 0px 5px;">25
  128. border-box; padding: 0px 5px;">26
  129. style="box-sizing: border-box; padding: 0px 5px;">27
  130. style="box-sizing: border-box; padding: 0px 
  131. 5px;">28
  132. 5px;">29
  133. 0px 5px;">30
  134. 0px 5px;">31
  135. padding: 0px 5px;">32
  136. padding: 0px 5px;">33
  137. border-box; padding: 0px 5px;">34
  138. border-box; padding: 0px 5px;">35
  139. style="box-sizing: border-box; padding: 0px 5px;">36
  140. style="box-sizing: border-box; padding: 0px 
  141. 5px;">37
  142. 5px;">38
  143. 0px 5px;">39
  144. 0px 5px;">40
  145. padding: 0px 5px;">41
  146. padding: 0px 5px;">42
  147.  

DualSync對象的f()方法在this上同步(通過在整個方法同步),g()的同步控制塊在syncObject對象上同步,因此,兩個同步控制相 互獨(dú)立,兩個方法同時魚腥,所以它們沒有在對象的同步控制上阻塞。因此,必須把訪問共享資源的代碼段包裝進(jìn)一個合適的同步控制塊。

6.線程有四個狀態(tài):新建、就緒、死亡、阻塞(程序能夠運(yùn)行,但有某個條件阻止它運(yùn)行)。進(jìn)入阻塞狀態(tài)的原因: 
1)通過調(diào)用sleep(miliseconds)使線程進(jìn)入休眠狀態(tài),在指定的時間內(nèi)不運(yùn)行。 
2)調(diào)用wait()使線程掛起,直到線程得道了notify()或notifyAll()消息,線程才會進(jìn)入就緒狀態(tài)。 
3)線程在等待某個輸入/輸出完成。 
4)線程在某個對象上調(diào)用其同步方法,但是對象鎖不可用。

7.線程之間為避免沖突,通過“握手機(jī)制”來進(jìn)行的,這種握手可以通過Object的方法wait()和notify()來安全的實(shí)現(xiàn)。注意,調(diào)用 sleep()的時候鎖并沒有被釋放,而調(diào)用wait()方法的確釋放了鎖,這就意味著,再調(diào)用wait()期間,可以調(diào)用線程對象中的其他同步控制方 法,當(dāng)一個線程在方法里遇到了對wait()的調(diào)用的時候,線程的執(zhí)行被掛起,對象上的鎖被釋放。 
wait()有兩種形式,一種與sleep()一樣接受毫秒數(shù),不同之處: 
1)在wait()期間對象鎖是釋放的。 
2)可以通過notify()、notifyAll(),或者指令時間到期,從wait()中回復(fù)執(zhí)行。 
另一種是不帶參數(shù)的,wait()將***等下去,知道接收到notify()或notifyAll()的消息。

8.wait()、notify()、notifyAll()這些方法是基類Object的一部分,而不是像sleep()那樣屬于Thread的一部 分。因?yàn)檫@些功能要用到的鎖也是所有對象的一部分,所以,你可以把wait()方法放在任何同步控制方法里,不用考慮這個類是否繼承Thread或者實(shí)現(xiàn) Runnable接口。只能在同步控制方法或同步控制塊中調(diào)用wait()、notify()、notifyAll()的線程在調(diào)用這些方法前必須“擁 有”(獲取)對象的鎖。(sleep不用操作鎖,所以可以在非同步控制方法里調(diào)用)。

  
 
  1. class="hljs java has-numbering" style="display: block; padding: 0px; 
  2. color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', 
  3. monospace;font-size:undefined; white-space: pre; border-top-left-radius: 
  4. 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; 
  5. border-bottom-left-radius: 0px; word-wrap: normal; background: 
  6. transparent;">
  7. 136); box-sizing: border-box;">synchronized(x){ 
  8.     x.notify(); 


網(wǎng)頁名稱:從零開始學(xué)Java有關(guān)線程的學(xué)習(xí)總結(jié)
分享網(wǎng)址:http://www.5511xx.com/article/djhppjp.html