synchronized

Java语言的关键字synchronized,可用来给对象和方法或者代码块加锁,当它锁定一个方法或者一个代码块的时候,同一时刻最多只有一个线程执行这个段代码。当两个并发线程访问同一个对象object中的这个加锁同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。然而,当一个线程访问object的一个加锁代码块时,另一个线程仍然可以访问该object中的非加锁代码块。 

 无论给方法或者代码块加锁,本质上是给对象加锁(个人理解)

public class Test {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread1 = new Thread(myRunnable, "thread1");
        Thread thread2 = new Thread(myRunnable, "thread2");
        thread1.start();
        thread2.start();
    }
}


public class MyRunnable implements Runnable{
    
    @Override
    public synchronized void run() {
        for(int i = 0; i < 5; i++ ){
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
}

thread1 0
thread1 1
thread1 2
thread1 3
thread1 4
thread2 0
thread2 1
thread2 2
thread2 3
thread2 4

    @Override
    public synchronized void run() {
        for(int i = 0; i < 5; i++ ){
            System.out.println(Thread.currentThread().getName() + " " + i);
        }
    }
//上面的函数等同于下面的函数,本质上是锁住this类对象
    @Override
    public void run() {
        synchronized(this) {
            for(int i = 0; i < 5; i++ ){
                System.out.println(Thread.currentThread().getName() + " " + i);
            }
        }
    }

 

 ------------------------------

public class Test {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread1 = new Thread(myRunnable, "thread1");
        thread1.start();

        for (int i = 0; i < 10000; i++) {
            myRunnable.integer = i;
        }
    }
}
public class MyRunnable implements Runnable {
    public Integer integer = 0;

    @Override
    public void run() {
        synchronized (integer) {
            for (int i = 0; i < 20; i++) {
                System.out.println(Thread.currentThread().getName() + " " + i
                        + "integer:" + integer);
            }
        }
    }    
}

结果可能是:

thread1 0integer:1179
thread1 1integer:2131
thread1 2integer:2131
thread1 3integer:2338
thread1 4integer:2509
thread1 5integer:2509
thread1 6integer:6470
thread1 7integer:6470

..............

synchronized (integer) 后并不阻止其它线程访问该对象,其它线程也可以"偷偷的"访问该对象。为了完全互斥,其它线程访问时必须synchronized(integer)
-------------------------
public class Test {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread thread1 = new Thread(myRunnable, "A");
        Thread thread2 = new Thread(myRunnable, "B");
        thread1.start();
        thread2.start();
    }
}

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        if (Thread.currentThread().getName().equals("A")) {
            a();
        } else {
            b();
        }
    }

    public synchronized void a() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }
    }

    public synchronized void b() {
        for (int i = 0; i < 6; i++) {
            System.out.println(Thread.currentThread().getName() + i);
        }
    }
}

result:

A0
A1
A2
A3
A4
B0
B1
B2
B3
B4
B5

不一定非要走同一段代码才互斥,只要两个线程synchronized同一个对象,那么后来的线程就必然会等待

posted @ 2015-02-20 13:05  牧 天  阅读(159)  评论(0)    收藏  举报