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