关于synchronized

Synchronized

  • 本质

    Synchronized 在底层关联的其实是一个 Monitor 对象,被 Synchronized 修饰的代码在运行前会先请求对应的 Monitor ,请求成功的话就继续运行,失败的话就说明该 Monitor 已经被占用了,然后阻塞掉,等待 Monitor 的释放。

    线程获得 Monitor 后(monitorenter) ,对应的 monitor 计数器加一(其实其他线程判断能不能获取到 monitor 就是看这个计数器是不是0,是0的话就代表可以直接运行),该线程执行完自己的代码后,释放 Monitor(monitorexit) ,计数器减一。对于同一个线程,该 Monitor 是可重入的。

    总的来说,Synchronized 其实也算是一种锁,锁的是对象或者类。当 synchronized 作用于普通方法上,锁的就是 this ,而对于静态方法而言就是锁的类。


  • 例子

    public class SynchronizedTest {
        public synchronized void method1(){
            for (int i=0;i<10;i++){
                System.out.println(Thread.currentThread().getName()+" : "+i);
            }
        }
        
        public synchronized void method2(){
            for (int i=0;i<10;i++){
                System.out.println(Thread.currentThread().getName()+" : "+i);
            }
        }
    
        public static void main(String[] args) {
            SynchronizedTest test = new SynchronizedTest();
            ExecutorService executorService = Executors.newCachedThreadPool();
            executorService.execute(()->test.method1());
            executorService.execute(()->test.method2());
        }
    }
    
关于synchronized_第1张图片
运行结果.png

从上面可以看到由于两个线程请求的都是同一个 SynchronizedTest 实例对象,因此其中一个必须阻塞,最终的结果就是两个线程的输出顺序都是有序的。

但如果 method2 不是同步的,输出结果当然有可能是打乱的。


关于synchronized_第2张图片
运行结果2.png

你可能感兴趣的:(关于synchronized)