Intrinsic Locks & Synchronized Statements

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




你可能感兴趣的:(java,线程,同步,锁)