public class SynchronizedBlock { public void test(String threadName){ synchronized (this){ for (int i=0;i<10;i++){ System.out.println("test--:"+threadName+" "+i); } } } public synchronized void test2(){ for (int i=0;i<10;i++){ System.out.println("test2-i:"+i); } } public static void main(String[] args) { final SynchronizedBlock syn1 = new SynchronizedBlock(); final ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new Runnable() { @Override public void run() { syn1.test(Thread.currentThread().getName()); } }); executorService.execute(new Runnable() { @Override public void run() { syn1.test(Thread.currentThread().getName()); } }); } }
上述代碼的運行結果如預期,兩個線程按順序輸出0-9ide
public static void main(String[] args) { final SynchronizedBlock syn1 = new SynchronizedBlock(); final SynchronizedBlock syn2 = new SynchronizedBlock(); final ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new Runnable() { @Override public void run() { syn1.test(Thread.currentThread().getName()); } }); executorService.execute(new Runnable() { @Override public void run() { syn2.test(Thread.currentThread().getName()); } }); }
若是是兩個實例,運行結果又會是怎樣呢?this
屢次的運行結果都不相同。能夠看出,synchronized修飾代碼塊和非靜態方法時,鎖定的對象都只是當前調用對象。線程
public class SynchronizedBlock { public void test(String threadName){ synchronized (SynchronizedBlock.class){ for (int i=0;i<10;i++){ System.out.println("test--:"+threadName+" "+i); } } } public synchronized static void test2(String threadName){ for (int i=0;i<10;i++){ System.out.println("test2--:"+threadName+" "+i); } } public static void main(String[] args) { final SynchronizedBlock syn1 = new SynchronizedBlock(); final SynchronizedBlock syn2 = new SynchronizedBlock(); final ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new Runnable() { @Override public void run() { syn1.test2(Thread.currentThread().getName()); } }); executorService.execute(new Runnable() { @Override public void run() { syn2.test2(Thread.currentThread().getName()); } }); } }
當synchronized修飾類和靜態方法時,鎖定的對象是這個類的全部實例。code
對於同一個實例,訪問該實例被synchronized修飾的兩個方法,會被阻塞嗎?對象
@Slf4j public class SynchronizedBlock2 { public synchronized void test2() { log.info("start test2---------------"); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } log.info("test2-----------"); } public synchronized void test3() { for (int i = 0; i < 10; i++) { log.info("test3--:{} " + i); } } public static void main(String[] args) { final SynchronizedBlock2 syn1 = new SynchronizedBlock2(); final ExecutorService executorService = Executors.newCachedThreadPool(); executorService.execute(new Runnable() { @Override public void run() { syn1.test2(); } }); executorService.execute(new Runnable() { @Override public void run() { syn1.test3(); } }); } }
答案是。。。。。。。。。。。。固然會blog
個人理解是這樣的,對於同一個實例來講,訪問test2方法時,至關於給它加了鎖,只有test2執行完,才能釋放鎖繼續執行test3。也不知道對不對,歡迎指正。get