先看测试方法:
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(); } }); } }}
- 多个线程同时访问多个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 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=2a.num=1003a.num=3003a.num=5004b.num=7004b.num=8004b.num=9004b.num=10004
由此可以看出:多线程在同一时刻只能有一个线程访问对象的synchronized方法
- 多线程同时访问一个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 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(); } }}
输出:
b.num=15b.num=16a.num=16b.num=16b.num=16b.num=16a.num=2016a.num=4016
由此看出:如果有线程访问synchronized方法,其他线程访问非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(); } } }}
输出:
b.num=1a.num=1002a.num=3002a.num=5003b.num=7003b.num=8003b.num=9003b.num=10004
由此可以看出:该用法和示例1作用相同
- 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 (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(); } } }}
输出:
b.num=2a.num=1003b.num=3003b.num=4004b.num=5004b.num=6004a.num=7004a.num=9004
结果同1
- 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 (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(); } } }}
输出:
b.num=1a.num=2b.num=1002b.num=2002a.num=2003b.num=3003b.num=4003a.num=4003
由此看出:访问a和b的线程互不影响