標籤:
Java的鎖分為對象鎖和類鎖。
1. 當兩個並發線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內針對該對象的操作只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。
2. 然而,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。
3. 尤其關鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對該object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
4. 同步加鎖的是對象,而不是代碼。因此,如果你的類中有一個同步方法,這個方法可以被兩個不同的線程同時執行,只要每個線程自己建立一個的該類的執行個體即可。
5. 不同的對象執行個體的synchronized方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象執行個體中的synchronized方法。
6. synchronized關鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中並不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法。
7.對一個全域對象或者類加鎖時,對該類的所有對象都起作用。
類鎖舉例
對一個全域變數加鎖:
1 public class MySynchronized extends Thread 2 { 3 private int val; 4 5 private static Object lock = new Object(); 6 7 public MySynchronized(int v) 8 { 9 val = v;10 }11 12 public void printVal(int v)13 {14 synchronized (lock)15 {16 while (true)17 {18 System.out.println(v);19 }20 }21 }22 23 public void run()24 {25 printVal(val);26 }27 }View Code
對整個類加鎖:
1 public class MySynchronized extends Thread 2 { 3 private int val; 4 5 public MySynchronized(int v) 6 { 7 val = v; 8 } 9 10 public void printVal(int v)11 {12 synchronized (MySynchronized.class)13 {14 while (true)15 {16 System.out.println(v);17 }18 }19 }20 21 public void run()22 {23 printVal(val);24 }25 }View Code
另外的鎖例子:
1 public class MySynchronized extends Thread 2 { 3 private String name; 4 5 private String val; 6 7 public MySynchronized(String name, String v) 8 { 9 this.name = name;10 val = v;11 }12 13 public void printVal()14 {15 synchronized (val)16 {17 while (true)18 {19 System.out.println(name + val);20 }21 }22 }23 24 public void run()25 {26 printVal();27 }28 29 public static void main(String args[])30 {31 MySynchronized f1 = new MySynchronized("Foo 1:", "printVal");32 f1.start();33 MySynchronized f2 = new MySynchronized("Foo 2:", "printVal");34 f2.start();35 }36 }View Code
String常量的特殊性,屬於同一個對象。
Java學習(十一):Java鎖Synchronized,對象鎖和類鎖舉例