1. 程式人生 > >每天一例多執行緒[day2]-----synchronized與多個執行緒多個鎖

每天一例多執行緒[day2]-----synchronized與多個執行緒多個鎖

package com.jeff.base.sync002;

  1. /**

  2. * 多個執行緒多個鎖

  3. *

  4. * 關鍵字synchronized取得的鎖都是物件鎖,而不是把一段程式碼(方法)當做鎖,

  5. * 所以程式碼中哪個執行緒先執行synchronized關鍵字的方法,哪個執行緒就持有該方法所屬物件的鎖(Lock),

  6. *

  7. * @author jeff

  8. *

  9. */

  10. public class MultiThread {

  11. private static int num = 0;

  12. /** static */

  13. public static synchronized void printNum(String tag){

  14. try {

  15. if(tag.equals("a")){

  16. num = 100;

  17. System.out.println("tag a, set num over!");

  18. Thread.sleep(1000);

  19. } else {

  20. num = 200;

  21. System.out.println("tag b, set num over!");

  22. }

  23. System.out.println("tag " + tag + ", num = " + num);

  24. } catch (InterruptedException e) {

  25. e.printStackTrace();

  26. }

  27. }

  28. //注意觀察run方法輸出順序

  29. public static void main(String[] args) {

  30. /**

  31. * 倆個不同的物件m1/m2:

  32. * 一個物件一把鎖,m1和m2兩個物件獲得的是自己的那一把物件鎖 ,兩者沒有任何關係,不存在同步問題。

  33. *

  34. * 在靜態型別的printNum方法上加synchronized關鍵字,表示鎖定.class類,類一級別的鎖(獨佔.class類)。

  35. * m1和m2兩個執行緒物件在訪問printNum時,訪問的是同一把鎖,

  36. * 所以最終的結果一定是:要麼先執行a的結果,再執行b的:

  37. * tag a, set num over!

  38. tag a, num = 100

  39. tag b, set num over!

  40. tag b, num = 200

  41. 要麼是先執行b的,再執行a的:

  42. tag b, set num over!

  43. tag b, num = 100

  44. tag a, set num over!

  45. tag a, num = 200

  46. *

  47. */

  48. final MultiThread m1 = new MultiThread();

  49. final MultiThread m2 = new MultiThread();

  50. Thread t1 = new Thread(new Runnable() {

  51. @Override

  52. public void run() {

  53. m1.printNum("a");

  54. }

  55. });

  56. Thread t2 = new Thread(new Runnable() {

  57. @Override

  58. public void run() {

  59. m2.printNum("b");

  60. }

  61. });

  62. t1.start();

  63. t2.start();

  64. }

  65. }

如果把printNum方法的static關鍵詞去掉,列印的結果:

  1. tag a, set num over!

  2. tag b, set num over!

  3. tag b, num = 200

  4. tag a, num = 200

也就是說,這兩個執行緒之間獲得的是自己的那一把鎖,多個執行緒多個鎖,各自無影響。