先看測試方法:java
package com.vincent; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Vincent 建立於 2016/5/11. */ public class Main { public static void main(String[] args) { ExecutorService threadPool = Executors.newCachedThreadPool(); final SynchronizedDemo synchronizedDemo=new SynchronizedDemo(); for (int i=0;i<5;i++){ threadPool.execute(new Runnable() { public void run() { synchronizedDemo.b(); } }); } for (int i=0;i<3;i++){ threadPool.execute(new Runnable() { public void run() { synchronizedDemo.a(); } }); } } }
package com.vincent; import java.util.concurrent.TimeUnit; /** * Vincent 建立於 2016/5/11. */ public class SynchronizedDemo { private Object lock1 = new Object(); private Object lock2 = new Object(); long currentTimeMillis = System.currentTimeMillis(); public synchronized void a() { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("a.num=" + num); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void b() { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("b.num=" + num); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }
輸出以下:多線程
b.num=2 a.num=1003 a.num=3003 a.num=5004 b.num=7004 b.num=8004 b.num=9004 b.num=10004
由此能夠看出:多線程在同一時刻只能有一個線程訪問對象的synchronized方法測試
package com.vincent; import java.util.concurrent.TimeUnit; /** * Vincent 建立於 2016/5/11. */ public class SynchronizedDemo { private Object lock1 = new Object(); private Object lock2 = new Object(); long currentTimeMillis = System.currentTimeMillis(); public synchronized void a() { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("a.num=" + num); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } public void b() { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("b.num=" + num); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } }
輸出:this
b.num=15 b.num=16 a.num=16 b.num=16 b.num=16 b.num=16 a.num=2016 a.num=4016
由此看出:若是有線程訪問synchronized方法,其餘線程訪問非synchronized方法不受影響線程
package com.vincent; import java.util.concurrent.TimeUnit; /** * Vincent 建立於 2016/5/11. */ public class SynchronizedDemo { private Object lock1 = new Object(); private Object lock2 = new Object(); long currentTimeMillis = System.currentTimeMillis(); public void a() { synchronized (this) { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("a.num=" + num); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } } public void b() { synchronized (this) { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("b.num=" + num); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }
輸出:code
b.num=1 a.num=1002 a.num=3002 a.num=5003 b.num=7003 b.num=8003 b.num=9003 b.num=10004
由此能夠看出:該用法和示例1做用相同對象
package com.vincent; import java.util.concurrent.TimeUnit; /** * Vincent 建立於 2016/5/11. */ public class SynchronizedDemo { private Object lock1 = new Object(); private Object lock2 = new Object(); long currentTimeMillis = System.currentTimeMillis(); public void a() { synchronized (lock1) { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("a.num=" + num); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } } public void b() { synchronized (lock1) { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("b.num=" + num); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }
輸出:it
b.num=2 a.num=1003 b.num=3003 b.num=4004 b.num=5004 b.num=6004 a.num=7004 a.num=9004
結果同1io
package com.vincent; import java.util.concurrent.TimeUnit; /** * Vincent 建立於 2016/5/11. */ public class SynchronizedDemo { private Object lock1 = new Object(); private Object lock2 = new Object(); long currentTimeMillis = System.currentTimeMillis(); public void a() { synchronized (lock1) { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("a.num=" + num); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } } } public void b() { synchronized (lock2) { long num = System.currentTimeMillis() - currentTimeMillis; System.out.println("b.num=" + num); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } }
輸出:class
b.num=1 a.num=2 b.num=1002 b.num=2002 a.num=2003 b.num=3003 b.num=4003 a.num=4003
由此看出:訪問a和b的線程互不影響