群里討論的一個問題,網上別人已經貼出了很詳細的說明,這里補充記錄下,后面加入個人測試代碼。
起因:1月份的時候看群里討論一道問題,問題內容如下:
一個日本作者-結成浩的《java多線程設計模式》有這樣的一個列子:
pulbic class Something(){ public synchronized void isSyncA(){} public synchronized void isSyncB(){} public static synchronized void cSyncA(){} public static synchronized void cSyncB(){} }
那么,加入有Something類的兩個實例a與b,那么下列組方法何以被1個以上線程同時訪問呢
a. x.isSyncA()與x.isSyncB()
b. x.isSyncA()與y.isSyncA()
c. x.cSyncA()與y.cSyncB()
d. x.isSyncA()與Something.cSyncA()
a,都是對同一個實例的synchronized域訪問,因此不能被同時訪問
b,是針對不同實例的,因此可以同時被訪問
c,因為是static synchronized,所以不同實例之間仍然會被限制,相當於Something.isSyncA()與 Something.isSyncB()了,因此不能被同時訪問。
那么,第d呢?,書上的 答案是可以被同時訪問的,答案理由是synchronzied的是實例方法與synchronzied的類方法由於鎖定(lock)不同的原因。
個人分析也就是synchronized 與static synchronized 相當於兩幫派,各自管各自,相互之間就無約束了,可以被同時訪問。目前還不是分清楚java內部設計synchronzied是怎么樣實現的。
結論:
A: synchronized static是某個類的范圍,synchronized static cSync{}防止多個線程同時訪問這個 類中的synchronized static 方法。它可以對類的所有對象實例起作用。
B: synchronized 是某實例的范圍,synchronized isSync(){}防止多個線程同時訪問這個實例中的synchronized 方法。
2.synchronized方法與synchronized代碼快的區別
synchronized methods(){} 與synchronized(this){}之間沒有什么區別,只是synchronized methods(){} 便於閱讀理解,而synchronized(this){}可以更精確的控制沖突限制訪問區域,有時候表現更高效率。
測試代碼:
測試環境:jdk1.6.0_30+eclipse3.7
import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * @author zm * */ public class SomeTest { public static int i; public synchronized void add(){ i+=1; print(); } public static synchronized void staticAdd(){ i+=1; print(); } public static void print(){ System.out.println(Thread.currentThread().getName() + " " + i); } public static void main(String[] args) throws InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(20); final CountDownLatch ready = new CountDownLatch(20); final CountDownLatch start = new CountDownLatch(1); final CountDownLatch end = new CountDownLatch(20); final SomeTest t = new SomeTest(); for(int i = 0; i < 20; i++){ pool.execute(new Runnable() { @Override public void run() { ready.countDown(); try { start.await(); } catch (InterruptedException e) { e.printStackTrace(); } t.add(); staticAdd(); end.countDown(); } }); } ready.await(); System.out.println("ready to execute..."); start.countDown(); end.await(); System.out.println("execute completed. close pool..."); pool.shutdown(); } }