Synchronized常用三種使用方式
1、修飾普通方法:鎖對象即為當前對象
2、修飾靜態方法:鎖對象為當前Class對象
3、修飾代碼塊:鎖對象為synchronized緊接着的小括號內的對象
一、驗證修飾普通方法時鎖對象
package com.demo; public class ThreadTest { public static void main(String[] args) { Thread t1 = new MyThread1(); Thread t2 = new MyThread2(t1); t1.start();// 默認priority=5 t2.start(); t2.setPriority(9);
System.out.println("線程1:" + t1.getState()); System.out.println("線程2:" + t2.getState()); } } class MyThread1 extends Thread { @Override public void run() { dosome(); } public synchronized void dosome() { System.out.println("mythread1"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("sleep end"); } } class MyThread2 extends Thread { private Object lock; public MyThread2(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println("mythread2"); } } }
現象:先逐行輸出mythread1,線程1:RUNNABLE,線程2:BLOCKED,之后暫停五分鍾,逐行輸出sleep end,mythread2
分析:線程2與線程1擁有相同的鎖,線程1優先級高於線程2,線程1優先執行,獲取到鎖,執行sleep,未釋放鎖,線程2未獲取到鎖,處於阻塞狀態,線程1sleep結束,輸出sleep end,並釋放鎖,線程2獲取到鎖,執行輸出mythread2
結論:當synchronized修飾普通方法時,鎖對象即為當前對象
二、驗證修飾靜態方法時鎖對象
對上述代碼稍作修改,在dosome方法上添加static關鍵字,main方法中,線程2對象初始化時,傳入MyThread1.class
現象:與上述現象一致
分析:同上
結論:當synchronized修飾靜態方法時,鎖對象為當前Class對象
三、驗證修飾代碼塊時鎖對象
package com.demo; public class ThreadTest { public static void main(String[] args) { Object o = new Object(); Thread t1 = new MyThread1(o); Thread t2 = new MyThread2(o); t1.start(); t2.start(); t2.setPriority(9); System.out.println("線程1:" + t1.getState()); System.out.println("線程2:" + t2.getState()); } } class MyThread1 extends Thread { private Object lock; public MyThread1(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println("mythread1"); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("sleep end"); } } } class MyThread2 extends Thread { private Object lock; public MyThread2(Object lock) { this.lock = lock; } @Override public void run() { synchronized (lock) { System.out.println("mythread2"); } } }
現象:同上
分析:同上
結論:當使用synchronized修改代碼塊時,其后小括號中的對象即為對象鎖。