synchronized是Java中的關鍵字,是一種同步鎖。它修飾的對象有以下幾種:
1. 修飾一個代碼塊,被修飾的代碼塊稱為同步語句塊,其作用的范圍是大括號{}括起來的代碼,作用的對象是調用這個代碼塊的對象;
2. 修飾一個方法,被修飾的方法稱為同步方法,其作用的范圍是整個方法,作用的對象是調用這個方法的對象;
3. 修改一個靜態的方法,其作用的范圍是整個靜態方法,作用的對象是這個類的所有對象;
4. 修改一個類,其作用的范圍是synchronized后面括號括起來的部分,作用主的對象是這個類的所有對象。
package com.fyb.concurrent; public class SynchronizedTest { private int num; public synchronized void method01(String arg) { try { if("a".equals(arg)){ num = 100; System.out.println("tag a set number over"); Thread.sleep(1000); }else{ num = 200; System.out.println("tag b set number over"); } System.out.println("tag = "+ arg + ";num ="+ num); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { final SynchronizedTest m1 = new SynchronizedTest(); final SynchronizedTest m2 = new SynchronizedTest(); Thread t1 = new Thread(new Runnable() { @Override public void run() { m1.method01("a"); } }); t1.start(); Thread t2 = new Thread(new Runnable() { @Override public void run() { m2.method01("b"); } }); t2.start(); } }
執行輸出:
tag a set number over tag b set number over tag = b;num =200 tag = a;num =100
可以看出,兩個不同的對象m1和m2的method01()方法執行並沒有互斥,因為這里synchronized是分別持有兩個對象的鎖。如果要想m1,m2兩個對象競爭同一個鎖,則需要在method01()上加上static修飾。如下:
package com.fyb.concurrent; public class SynchronizedTest { private static int num; public static synchronized void method01(String arg) { try { if("a".equals(arg)){ num = 100; System.out.println("tag a set number over"); Thread.sleep(1000); }else{ num = 200; System.out.println("tag b set number over"); } System.out.println("tag = "+ arg + ";num ="+ num); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { final SynchronizedTest m1 = new SynchronizedTest(); final SynchronizedTest m2 = new SynchronizedTest(); Thread t1 = new Thread(new Runnable() { @Override public void run() { m1.method01("a"); } }); t1.start(); Thread t2 = new Thread(new Runnable() { @Override public void run() { m2.method01("b"); } }); t2.start(); } }
輸出結果:
tag a set number over tag = a;num =100 tag b set number over tag = b;num =200
小結:
synchronized修飾不加static的方法,鎖是加在單個對象上,不同的對象沒有競爭關系;修飾加了static的方法,鎖是加載類上,這個類所有的對象競爭一把鎖。