使用Synchronized塊同步方法
nchronized關(guān)鍵字有兩種用法。第一種就是在《使用Synchronized關(guān)鍵字同步類方法》一文中所介紹的直接用在方法的定義中。另外一種就是synchronized塊。我們不僅可以通過synchronized塊來同步一個對象變量。也可以使用synchronized塊來同步類中的靜態(tài)方法和非靜態(tài)方法。
synchronized塊的語法如下public void method()
2.{
3. … …
4. synchronized(表達式)
5. {
6. … …
7. }
8.}
一、非靜態(tài)類方法的同步
從《使用Synchronized關(guān)鍵字同步類方法》一文中我們知道使用synchronized關(guān)鍵字來定義方法就會鎖定類中所有使用synchronzied關(guān)鍵字定義的靜態(tài)方法或非靜態(tài)方法,但這并不好理解。而如果使用synchronized塊來達到同樣的效果,就不難理解為什么會產(chǎn)生這種效果了。如果想使用synchronized塊來鎖定類中所有的同步非靜態(tài)方法,需要使用this做為synchronized塊的參數(shù)傳入synchronized塊國,代碼如下
通過synchronized塊同步非靜態(tài)方法
9.public class SyncBlock
10. {
11. public void method1()
12. {
13. synchronized(this) // 相當(dāng)于對method1方法使用synchronized關(guān)鍵字
14. {
15. … …
16. }
17. }
18. public void method2()
19. {
20. synchronized(this) // 相當(dāng)于對method2方法使用synchronized關(guān)鍵字
21. {
22. … …
23. }
24. }
25. public synchronized void method3()
26. {
27. … …
28. }
29. }
在上面的代碼中的method1和method2方法中使用了synchronized塊。而第017行的method3方法仍然使用synchronized關(guān)鍵字來定義方法。在使用同一個SyncBlock類實例時,這三個方法只要有一個正在執(zhí)行,其他兩個方法就會因未獲得同步鎖而被阻塞。在使用synchronized塊時要想達到和synchronized關(guān)鍵字同樣的效果,必須將所有的代碼都寫在synchronized塊中,否則,將無法使當(dāng)前方法中的所有代碼和其他的方法同步。
除了使用this做為synchronized塊的參數(shù)外,還可以使用SyncBlock.this作為synchronized塊的參數(shù)來達到同樣的效果。
在內(nèi)類(InnerClass)的方法中使用synchronized塊來時,this只表示內(nèi)類,和外類(OuterClass)沒有關(guān)系。但內(nèi)類的非靜態(tài)方法可以和外類的非靜態(tài)方法同步。如在內(nèi)類InnerClass中加一個method4方法,并使method4方法和SyncBlock的三個方法同步,代碼如下:
使內(nèi)類的非靜態(tài)方法和外類的非靜態(tài)方法同步
30.public class SyncBlock
31.{
32. … …
33. class InnerClass
34. {
35. public void method4()
36. {
37. synchronized(SyncBlock.this)
38. {
39. … …
40. }
41. }
42. }
43. … …
44.}
在上面SyncBlock類的新版本中,InnerClass類的method4方法和SyncBlock類的其他三個方法同步,因此,method1、method2、method3和method4四個方法在同一時間只能有一個方法執(zhí)行。
Synchronized塊不管是正常執(zhí)行完,還是因為程序出錯而異常退出synchronized塊,當(dāng)前的synchronized塊所持有的同步鎖都會自動釋放。因此,在使用synchronized塊時不必擔(dān)心同步鎖的釋放問題。
nchronized關(guān)鍵字有兩種用法。第一種就是在《使用Synchronized關(guān)鍵字同步類方法》一文中所介紹的直接用在方法的定義中。另外一種就是synchronized塊。我們不僅可以通過synchronized塊來同步一個對象變量。也可以使用synchronized塊來同步類中的靜態(tài)方法和非靜態(tài)方法。
synchronized塊的語法如下public void method()
2.{
3. … …
4. synchronized(表達式)
5. {
6. … …
7. }
8.}
一、非靜態(tài)類方法的同步
從《使用Synchronized關(guān)鍵字同步類方法》一文中我們知道使用synchronized關(guān)鍵字來定義方法就會鎖定類中所有使用synchronzied關(guān)鍵字定義的靜態(tài)方法或非靜態(tài)方法,但這并不好理解。而如果使用synchronized塊來達到同樣的效果,就不難理解為什么會產(chǎn)生這種效果了。如果想使用synchronized塊來鎖定類中所有的同步非靜態(tài)方法,需要使用this做為synchronized塊的參數(shù)傳入synchronized塊國,代碼如下
通過synchronized塊同步非靜態(tài)方法
9.public class SyncBlock
10. {
11. public void method1()
12. {
13. synchronized(this) // 相當(dāng)于對method1方法使用synchronized關(guān)鍵字
14. {
15. … …
16. }
17. }
18. public void method2()
19. {
20. synchronized(this) // 相當(dāng)于對method2方法使用synchronized關(guān)鍵字
21. {
22. … …
23. }
24. }
25. public synchronized void method3()
26. {
27. … …
28. }
29. }
在上面的代碼中的method1和method2方法中使用了synchronized塊。而第017行的method3方法仍然使用synchronized關(guān)鍵字來定義方法。在使用同一個SyncBlock類實例時,這三個方法只要有一個正在執(zhí)行,其他兩個方法就會因未獲得同步鎖而被阻塞。在使用synchronized塊時要想達到和synchronized關(guān)鍵字同樣的效果,必須將所有的代碼都寫在synchronized塊中,否則,將無法使當(dāng)前方法中的所有代碼和其他的方法同步。
除了使用this做為synchronized塊的參數(shù)外,還可以使用SyncBlock.this作為synchronized塊的參數(shù)來達到同樣的效果。
在內(nèi)類(InnerClass)的方法中使用synchronized塊來時,this只表示內(nèi)類,和外類(OuterClass)沒有關(guān)系。但內(nèi)類的非靜態(tài)方法可以和外類的非靜態(tài)方法同步。如在內(nèi)類InnerClass中加一個method4方法,并使method4方法和SyncBlock的三個方法同步,代碼如下:
使內(nèi)類的非靜態(tài)方法和外類的非靜態(tài)方法同步
30.public class SyncBlock
31.{
32. … …
33. class InnerClass
34. {
35. public void method4()
36. {
37. synchronized(SyncBlock.this)
38. {
39. … …
40. }
41. }
42. }
43. … …
44.}
在上面SyncBlock類的新版本中,InnerClass類的method4方法和SyncBlock類的其他三個方法同步,因此,method1、method2、method3和method4四個方法在同一時間只能有一個方法執(zhí)行。
Synchronized塊不管是正常執(zhí)行完,還是因為程序出錯而異常退出synchronized塊,當(dāng)前的synchronized塊所持有的同步鎖都會自動釋放。因此,在使用synchronized塊時不必擔(dān)心同步鎖的釋放問題。