1,鎖重用,若是一個方法用synchronized修飾,而且這個方法中引入了其餘的用synchronized修飾的方法,那麼線程執行這個方法的時候,會自動獲取方法中的其餘方法鎖。java
例子:多線程
public class SynchronzedClass { public synchronized void a(){ b(); } public synchronized void b(){ System.out.println("b method"); } } public class SynMainClass { public static void main(String[] args) { Thread t = new Thread(); final SynchronzedClass syb = new SynchronzedClass(); Thread t1 = new Thread(new Runnable() { @Override public void run() { syb.a(); } }); t1.start(); } } 結果:b method
2,同步不具備繼承性ide
例子:this
public class FatherClass { public synchronized void a(){ try { System.out.println("father begin :"+Thread.currentThread().getName()); Thread.sleep(5000); System.out.println("father end :"+Thread.currentThread().getName()); } catch (InterruptedException e) { e.printStackTrace(); } } private class SunClass extends FatherClass{ @Override public void a() { try { System.out.println("son begin:"+Thread.currentThread().getName()); Thread.sleep(5000); System.out.println("son end:"+Thread.currentThread().getName()); super.a(); } catch (InterruptedException e) { e.printStackTrace(); } } } private class Thread1 extends Thread{ private SunClass sunClass; public Thread1(SunClass sunClass){ this.sunClass = sunClass; } @Override public void run() { sunClass.a(); super.run(); } } private class Thread2 extends Thread{ private SunClass sunClass; public Thread2(SunClass sunClass){ this.sunClass = sunClass; } @Override public void run() { sunClass.a(); super.run(); } } public static void main(String[] args) { FatherClass f = new FatherClass(); SunClass son = f.new SunClass(); Thread1 t1 = f.new Thread1(son); Thread2 t2 = f.new Thread2(son); t1.setName("a"); t2.setName("b"); t1.start(); t2.start(); } } 結果:son begin:a son begin:b son end:b son end:a father begin :b father end :b father begin :a father end :a 能夠看到子類繼承的方法在多線程的狀況下是不一樣步的,可是他們的父類被繼承的方法是同步的,這個例子是 用內部類的方法實現的,此規則在非內部類狀況下依然適用。
3,當一個線程出現異常的時候,會釋放他所持有的鎖spa
public class ExceptionThread { private class Demo{ private int a=0; public synchronized void test(){ if(Thread.currentThread().getName().equals("a")){ System.out.println(12/a); }else{ System.out.println("b method"); } } } private class Thread1 extends Thread{ private Demo e; Thread1(Demo e){ this.e = e; } @Override public void run() { e.test(); super.run(); } } private class Thread2 extends Thread{ private Demo e; Thread2(Demo e){ this.e = e; } @Override public void run() { e.test(); super.run(); } } public static void main(String[] args) { ExceptionThread e = new ExceptionThread(); Demo d = e.new Demo(); Thread1 t1 = e.new Thread1(d); Thread2 t2 = e.new Thread2(d); t1.setName("a"); t2.setName("b"); t1.start(); t2.start(); } } 結果:Exception in thread "a" b method java.lang.ArithmeticException: / by zero at com.qsfs.thread.synch.use.ExceptionThread$Demo.test(ExceptionThread.java:8) at com.qsfs.thread.synch.use.ExceptionThread$Thread1.run(ExceptionThread.java:22)
4,(1)synchronized 方法()與synchronized(this){}等效的 ,鎖的都是對象
線程
public class ThisThread { public void test(){ synchronized(this){ try { System.out.println("begin"+Thread.currentThread().getName()); Thread.sleep(3000); System.out.println("begin"+Thread.currentThread().getName()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } private class Thread1 extends Thread{ private ThisThread e; Thread1(ThisThread e){ this.e = e; } @Override public void run() { e.test(); super.run(); } } private class Thread2 extends Thread{ private ThisThread e; Thread2(ThisThread e){ this.e = e; } @Override public void run() { e.test(); super.run(); } } public static void main(String[] args) { ThisThread d = new ThisThread(); ThisThread d1 = new ThisThread(); Thread1 t1 = d.new Thread1(d); Thread2 t2 = d.new Thread2(d1); t1.setName("a"); t2.setName("b"); t1.start(); t2.start(); } }
(2)synchronized static 方法()與syncjronized(類.class)等效的,鎖的都是類,此類生成的對象都會被鎖住(方法,或者相同的鑰匙)
code
public class ClassSynchronizedThread { private synchronized static void test1() throws InterruptedException{ System.out.println("begin method Synchronized"+Thread.currentThread().getName()); Thread.sleep(3000); System.out.println("end method Synchronized"+Thread.currentThread().getName()); } private void test2() throws InterruptedException{ synchronized(ClassSynchronizedThread.class){ System.out.println("begin synchronized block"+Thread.currentThread().getName()); Thread.sleep(3000); System.out.println("end synchronized block"+Thread.currentThread().getName()); } } private class Thread1 extends Thread{ private ClassSynchronizedThread e; Thread1(ClassSynchronizedThread e){ this.e = e; } @Override public void run() { try { e.test1(); e.test2(); } catch (InterruptedException e1) { e1.printStackTrace(); } super.run(); } } private class Thread2 extends Thread{ private ClassSynchronizedThread e; Thread2(ClassSynchronizedThread e){ this.e = e; } @Override public void run() { try { e.test1(); e.test2(); } catch (InterruptedException e) { e.printStackTrace(); } super.run(); } } public static void main(String[] args) { ClassSynchronizedThread d1 = new ClassSynchronizedThread(); ClassSynchronizedThread d2 = new ClassSynchronizedThread(); Thread1 t1 = d1.new Thread1(d1); Thread2 t2 = d1.new Thread2(d2); t1.setName("a"); t2.setName("b"); t1.start(); t2.start(); } }
5,一個類中可能有不少個內部類,這些類中頗有可能就會有一些霸道的,好比一個內部類中方法的鎖的對象可能就是其餘內部類的對象,那麼訪問這個方法的線程與訪問這個對象中靜態方法的線程是同步執行的對象
public class objec { class A{ private B b; private void test(B b){ this.b = b; synchronized(b){ for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } } } class B{ public synchronized void test1(){ for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getName()+":"+i); } } } public static void main(String[] args) { objec o = new objec(); final A a = o.new A(); final B b = o.new B(); Thread t1 = new Thread(new Runnable() { @Override public void run() { a.test(b); } },"a"); Thread t2 = new Thread(new Runnable() { @Override public void run() { b.test1(); } },"b"); t1.start(); t2.start(); } } 結果: a:0 a:1 a:2 a:3 a:4 b:0 b:1 b:2 b:3 b:4 靜態內部類和普通內部類都適用
6,synchronized(對象),若是對象不變,即便是屬性變了,也不會影響效果繼承