并发

Java并发(三)synchronized、volatile以及

2018-06-24  本文已影响15人  黄金矿工00七

今天说一下并发的基本同步工具synchronized以及volatile。


public class Test {

  static final Test object = new Test();
  static final Test object1 = new Test();
  public static void main(String[] args) throws InterruptedException {
    Test t = new Test();
   new Thread(new Runnable() {
     @Override
     public void run() {
       t.test();
     }
   }).start();

  }

  int a(int a) {
    if (a == 0) {
      throw new NullPointerException();
    } else {
      return a;
    }
  }

  public void test() {

    synchronized (object) {
      //进入同步快,获取锁
      try {
        System.out.println(Thread.currentThread().getId() + "获得锁");
        Thread.sleep(3000);
        //当前同步块结束,释放锁
        System.out.println(Thread.currentThread().getId() + "释放锁");
      } catch (InterruptedException e) {

      }
    }
  }

这里的代码大家可以自己运行一下,这只是让大家便于理解,下面我们来看一下程序实际是如何运行的,我把test()的字节码给大家标注了一下

 // 获取Test类静态实例对象字段,将值压入操作数栈顶
 0 getstatic #11 <Test.object>
 //复制栈顶数值并将复制值压入栈顶
 3 dup
 //将栈顶引用类型数值存入第2个本地变量
 4 astore_1
 //获得对象锁
 5 monitorenter
 6 getstatic #12 <java/lang/System.out>
 9 new #13 <java/lang/StringBuilder>
12 dup
13 invokespecial #14 <java/lang/StringBuilder.<init>>
16 invokestatic #15 <java/lang/Thread.currentThread>
19 invokevirtual #16 <java/lang/Thread.getId>
22 invokevirtual #17 <java/lang/StringBuilder.append>
25 ldc #18 <获得锁>
27 invokevirtual #19 <java/lang/StringBuilder.append>
30 invokevirtual #20 <java/lang/StringBuilder.toString>
33 invokevirtual #21 <java/io/PrintStream.println>
36 ldc2_w #22 <3000>
39 invokestatic #24 <java/lang/Thread.sleep>
42 getstatic #12 <java/lang/System.out>
45 new #13 <java/lang/StringBuilder>
48 dup
49 invokespecial #14 <java/lang/StringBuilder.<init>>
52 invokestatic #15 <java/lang/Thread.currentThread>
55 invokevirtual #16 <java/lang/Thread.getId>
58 invokevirtual #17 <java/lang/StringBuilder.append>
61 ldc #25 <释放锁>
63 invokevirtual #19 <java/lang/StringBuilder.append>
66 invokevirtual #20 <java/lang/StringBuilder.toString>
69 invokevirtual #21 <java/io/PrintStream.println>
72 goto 76 (+4)
75 astore_2
76 aload_1
//释放对象锁
77 monitorexit
//没有异常发生,直接返回
78 goto 86 (+8)
81 astore_3
82 aload_1
//这里是catch块中,当发行异常,无条件释放锁
83 monitorexit
84 aload_3
85 athrow
86 return

可以看到,synchronized在底层是如何运行的。

上一篇 下一篇

猜你喜欢

热点阅读