我的總結:
java
synchronized 不能夠被繼承。 synchronized 修飾this,則表明鎖住對象,同一個對象互斥。 synchronized 修飾XXX.class,則表明鎖住字節碼,跟鎖住同一個類的class的邏輯和static function互斥。 synchronized 修飾靜態變量,則對於全部具備相同屬性值的對象互斥。 synchronized 修飾普通變量,則對於同一個對象,在該屬性值未變更以前互斥。 synchronized 修飾靜態方法,則對於全部對象訪問該方法互斥。 synchronized 修飾普通方法,則對同一個對象訪問該方法互斥。 一、非static方法 synchronized void method1()與void method1(){synchronized(this){}}是等價,都是對象鎖,鎖定固然對象實例。 二、static方法 static synchronized void method1()與static void method1(){ synchronized (Foo.class){}}是等價,是等價的,鎖定Class的字節碼。 sleep和wait的區別有: 1,這兩個方法來自不一樣的類分別是Thread和Object 2,最主要是sleep方法沒有釋放鎖,而wait方法釋放了鎖,使得其餘線程可使用同步控制塊或者方法。 3,wait,notify和notifyAll只能在同步控制方法或者同步控制塊裏面使用,而sleep能夠在 任何地方使用 synchronized(x){ x.notify() //或者wait() } 4,sleep必須捕獲異常,而wait,notify和notifyAll不須要捕獲異常 5,調用sleep()和yield()的時候鎖並無被釋放,而調用wait()將釋放鎖。這樣另外一個任務(線程)能夠得到當前對象的鎖, 從而進入它的synchronized方法中。能夠經過notify()/notifyAll(),或者時間到期,從wait()中恢復執行。 只能在同步控制方法或同步塊中調用wait()、notify()和notifyAll()。 若是在非同步的方法裏調用這些方法,在運行時會拋出IllegalMonitorStateException異常。
(若是有錯誤的地方或者沒有說明白的地方,請你們指出來,謝謝。)
ide
Foo 類 class Foo { private String name; private static String desc; private byte[] b = new byte[10]; private static Foo foo; private Foo() { // TODO Auto-generated constructor stub } public static Foo getInstance(){ if(null == foo ){ foo = new Foo(); } return foo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public static String getDesc() { return desc; } public static void setDesc(String desc) { Foo.desc = desc; } public byte[] getB() { return b; } public void setB(byte[] b) { this.b = b; } public synchronized static void methodOne(String flag) { System.out.println("methodOne"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodTwo(String flag) { System.out.println("**methodTwo**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } public void methodThrid(String flag){ synchronized (this) { System.out.println("**methodThrid**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodFour(String flag){ //synchronized鎖住屬性值,若是對於同一個對象,若是該屬性值同樣,則會互斥,若是不同的話,則不會互斥。 synchronized (name) { System.out.println("**name**"+flag+name); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodFive(String flag){ //synchronized鎖住靜態屬性值,若是這個屬性值相同,則互斥,不然不互斥。 synchronized (desc) { System.out.println("**desc**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodSix(String flag){ synchronized (b) { System.out.println("**b**"+flag+b); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodSeven(String flag){ //synchronized鎖住class的時候,會跟class裏面的static function 互斥,不會跟普通function互斥。 synchronized (Foo.class) { System.out.println("**Foo.class**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
main 方法測試程序 for (int i = 0; i < 5; i++) { // start two thread new Thread(new Runnable() { @Override public void run() { Foo f = Foo.getInstance(); f.setName("tttt"); //Foo.setDesc("ooo"); //f.methodTwo(Thread.currentThread().getName()); //Foo.methodOne(Thread.currentThread().getName()); //f.methodFour(Thread.currentThread().getName()); //f.methodFive(Thread.currentThread().getName()); //f.methodSeven(Thread.currentThread().getName()); f.methodSix(Thread.currentThread().getName()); } }).start(); new Thread(new Runnable() { @Override public void run() { Foo f = Foo.getInstance(); f.setName("pppp"); //Foo.setDesc("zzz"); //f.methodTwo(Thread.currentThread().getName()); //f.methodThrid(Thread.currentThread().getName()); //f.methodFour(Thread.currentThread().getName()); //Foo.methodOne(Thread.currentThread().getName()); //f.methodFive(Thread.currentThread().getName()); //f.methodSeven(Thread.currentThread().getName()); //f.methodSix(Thread.currentThread().getName()); } }).start(); }