Java支持多個線程同時訪問一個對象或者對象的成員變量,synchronized 關鍵字可以修飾方法或者同步代碼塊的方法,確保多個線程在同一時刻,只能有一個線程處於方法或者同步代碼塊中,保證了線程對變量訪問的可見性和排他性
public class Demo052501 { private static class ThreadDemo implements Runnable{ private Integer i; public ThreadDemo(Integer i){ this.i = i; } @Override public void run() { synchronized (i){ Thread thread = Thread.currentThread(); System.out.println(thread.getName() + "-------"+ i+ "@----" + System.identityHashCode(this.i)); i++; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { ThreadDemo worker = new ThreadDemo(1); for(int i =0;i<6;i++){ new Thread(worker).start(); } } }
預期輸出:
i : 1-2-3-4-5-6
實際輸出:
錯誤加鎖原因:
.class 文件反編譯,i++ 的代碼爲:
Integer.valueOf()
synchronized 內置鎖,鎖的是對象,保證對象唯一!!!
解決方法
public class Demo052501 { private static class ThreadDemo implements Runnable{ private Integer i; private Object o = new Object(); public ThreadDemo(Integer i){ this.i = i; } @Override public void run() { synchronized (o){ Thread thread = Thread.currentThread(); System.out.println(thread.getName() + "-------"+ i+ "@----" + System.identityHashCode(this.i)); i++; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public static void main(String[] args) { ThreadDemo worker = new ThreadDemo(1); for(int i =0;i<6;i++){ new Thread(worker).start(); } } }