Java的同步建立在intrinsic lock(也称为monitor lock)的基础之上,intrinsic lock用于保证对指定对象状态的排他性访问及建立happens-before关系。每一个对象都有一个instrinsic lock与之关联。当一个线程拥有了一个intrinsic lock之后,其他线程就无法获得该instrinsic lock,直到该lock被释放。
使用synchronized statements时,必须指定一个提供了intrinsic lock的对象。
public class MyApp implements Runnable { public int count; Object obj = new Object(); public MyApp(int count) { this.count = count; System.out.println("MyRunnable's constructor!"); } private void incre() throws InterruptedException { synchronized (this) { for (int i = 0; i < 100; i++) { count++; System.out.println(count); Thread.sleep(10); } } } private void decre() throws InterruptedException { synchronized (this) { for (int i = 0; i < 100; i++) { count--; System.out.println(count); Thread.sleep(10); } } } @Override public void run() { try { if (count == 0) incre(); else decre(); } catch (InterruptedException ex) { } } public static void main(String[] args) { MyApp app = new MyApp(0); Thread t1 = new Thread(app); Thread t2 = new Thread(app); t1.start(); t2.start(); } }
也可以不使用this作为intrinsic lock,如下:
public class MyApp implements Runnable { public int count; Object obj = new Object(); public MyApp(int count) { this.count = count; System.out.println("MyRunnable's constructor!"); } private void incre() throws InterruptedException { synchronized (this) { for (int i = 0; i < 100; i++) { count++; System.out.println(count); Thread.sleep(10); } } } private void decre() throws InterruptedException { synchronized (this) { for (int i = 0; i < 100; i++) { count--; System.out.println(count); Thread.sleep(10); } } } @Override public void run() { try { if (count == 0) incre(); else decre(); } catch (InterruptedException ex) { } } public static void main(String[] args) { MyApp app = new MyApp(0); Thread t1 = new Thread(app); Thread t2 = new Thread(app); t1.start(); t2.start(); } }
如果两个synchronized statements使用了同一个intrinsic lock,那么这两个synchronized statements就不能同时执行,如下:
public class MyApp implements Runnable { public static int count = 0; Object lock = new Object(); public MyApp() { System.out.println("MyRunnable's constructor!"); } private void f1() throws InterruptedException { synchronized (lock) { for (int i = 0; i < 3; i++) { System.out.println("f1: " + i); Thread.sleep(1000); } System.out.println("f1 is down"); } } private void f2() throws InterruptedException { System.out.println("enter f2"); synchronized (lock) { for (int i = 10; i < 13; i++) { System.out.println("f2: " + i); Thread.sleep(1000); } System.out.println("f2 is down"); } } @Override public void run() { try { if (0 == count) f1(); else if (1 == count) f2(); } catch (InterruptedException ex) { } } public static void main(String[] args) throws InterruptedException { MyApp app = new MyApp(); Thread t1 = new Thread(app); t1.start(); Thread.sleep(500); app.count = 1; Thread t2 = new Thread(app); t2.start(); System.out.println("main is down"); } }运行结果为
MyRunnable's constructor!
f1: 0
main is down
enter f2
f1: 1
f1: 2
f1 is down
f2: 10
f2: 11
f2: 12
f2 is down