Synchronized代码块锁的是什么?全局锁?对象锁?

对象锁:锁的是这个对象。

全局锁:锁的是那个写了synchronized关键字的方法或者代码块。

这里主要去聊全局锁

当java关键字 Synchronized()代码块锁随便的一个类比如,Integer.class时(或者一个静态变量(前提是不改变指向))

比如下列代码

package cn.com.demo.utils;

import lombok.Getter;

import java.util.stream.IntStream;

/**
 * @author JMWANG
 */
public class Tes2Thread {
    @Getter
    private static int counter = 0;
    public static int reset() {
        counter = 0;
        return counter;
    }
    private static Integer locker = new Integer(0);
    public void right() {
        synchronized (locker) {
            counter++;
        }
    }

    public static void main(String[] args) {
        Tes2Thread.reset();
        //多线程循环一定次数调用Data类不同实例的wrong方法
        IntStream.rangeClosed(1, 1000000).parallel().forEach(i -> new Tes2Thread().right());

        System.out.println(Tes2Thread.getCounter());
    }
}

最后得到的解决无疑是1000000,但是明明被保护的对象是 公共静态变量counter ,为什么要锁一个毫无关系的一个类(或者一个静态不变的对象实例)。最后达到的效果确实保护了 这个counter 变量。

从字节码来分析

  public void right();
    Code:
       0: getstatic     #3                  // Field locker:Ljava/lang/Integer;
       3: dup
       4: astore_1
       5: monitorenter						//通过Synchronized获取了一个监视器,将静态的所有数据都保护了起来,并且进行了操作。
       6: getstatic     #2                  // Field counter:I
       9: iconst_1
      10: iadd
      11: putstatic     #2                  // Field counter:I
      14: aload_1
      15: monitorexit						//退出监视器
      16: goto          24
      19: astore_2
      20: aload_1
      21: monitorexit
      22: aload_2
      23: athrow
      24: return
    Exception table:
       from    to  target type
           6    16    19   any
          19    22    19   any

当监视器启动这是我们使用的是全局锁。当全局锁进入了monitor就不会让其他线程进入,只能等待。从而达到同步的效果。


版权声明:本文为jj89929665原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。