synchronized(class)与synchronized(this)

来源:互联网 发布:淘宝卖家1000被骗案例 编辑:程序博客网 时间:2024/05/04 05:02

转载:http://www.cnblogs.com/highriver/archive/2011/12/18/2291965.html

synchronized(class)很特别,它会让另一个线程在任何需要获取class做为monitor的地方等待.class与this做为不同的监视器可以同时使用,不存在一个线程获取了class,另一个线程就不能获取该class的一切实例.

根据下面的代码自行修改,分别验证下面的几种情况:
synchronized(class)
synchronized(this)
->线程各自获取monitor,不会有等待,线程交替输出,两个线程可以同时并发执行。
synchronized(this)
synchronized(this)
->如果不同线程监视同一个实例对象,就会等待(一个线程全部执行完后,另一个线程再执行),如果不同的实例,不会等待.
synchronized(class)
synchronized(class)
->如果不同线程监视同一个实例或者不同的实例对象,都会等待.

package com.h.test;        import java.util.concurrent.ExecutorService;        import java.util.concurrent.Executors;/** * Created by John on 2017/8/26. */public class SynTest implements Runnable{    private static boolean flag;    public static synchronized void test1(){ //静态同步方法,监视器=class        for (int i = 0; i < 100; i++) {            System.out.println("test1:" + i);        }    }    public void test2(){        synchronized (this){//注意this做为监视器.它与class分别是二个不同监视器.不会存在class被获取,this就要等的现象.这也是我以前关于监视器的一个误区.            for (int i = 0; i < 100; i++) {                System.out.println("test2:" + i);            }        }    }    public void test3(){        synchronized (this){            for (int i = 0; i < 100; i++) {                System.out.println("test3:" + i);            }        }    }    public void test4(){        synchronized (SynTest.class){// 显示使用获取class做为监视器,与static synchronized method隐式获取class监视器一样.            for (int i = 0; i < 100; i++) {                System.out.println("test4:" + i);            }        }    }    @Override    public void run() {        // flag是static的变量.所以,不同的线程会执行不同的方法,只有这样才能看到不同的锁定效果.        if (flag){            flag = false;            test1();            //test4();            // test3();        }else{            flag = true;            //test2();            test4();        }    }    public static void main(String[] args) {        ExecutorService service = Executors.newFixedThreadPool(2);        SynTest s1 = new SynTest();        SynTest s2 = new SynTest();        service.execute(s1);        service.execute(s2);        //service.execute(s1);        service.shutdown();    }}