zoukankan      html  css  js  c++  java
  • volatile关键字和synchronized关键字

    volatile关键字:

    可以用来修饰字段(成员变量),就是告知程序任何对该变量的访问均需要从共享内存中获取,而对它的改变必须同步刷新回共享内存,它能保证所有线程对变量访问的可见性。

    synchronized关键字:

    可以修饰方法或以同步块的形式来进行使用,它主要确保多个线程在同一时刻,只能有一个线程处于方法或者同步块中,它保证了对变量访问的可见性和排他性。

    package com.baidu.nuomi.concurrent;
    
    /**
     * Created by sonofelice on 16/6/18.
     */
    public class Synchronized {
        public static void main(String[] args) {
            synchronized (Synchronized.class){
    
            }
        }
        public static synchronized void m(){}
    }

    使用javap查看生成的class文件:

    在该类的同级目录下执行javap -v Synchronized.class

    得到下面的结果:

    Classfile /Users/sonofelice/Downloads/zhmmself/target/classes/com/baidu/nuomi/concurrent/Synchronized.class
      Last modified 2016-6-18; size 590 bytes
      MD5 checksum 64550d9817510bcc5d531e20e814b122
      Compiled from "Synchronized.java"
    public class com.baidu.nuomi.concurrent.Synchronized
      SourceFile: "Synchronized.java"
      minor version: 0
      major version: 50
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #3.#22         //  java/lang/Object."<init>":()V
       #2 = Class              #23            //  com/baidu/nuomi/concurrent/Synchronized
       #3 = Class              #24            //  java/lang/Object
       #4 = Utf8               <init>
       #5 = Utf8               ()V
       #6 = Utf8               Code
       #7 = Utf8               LineNumberTable
       #8 = Utf8               LocalVariableTable
       #9 = Utf8               this
      #10 = Utf8               Lcom/baidu/nuomi/concurrent/Synchronized;
      #11 = Utf8               main
      #12 = Utf8               ([Ljava/lang/String;)V
      #13 = Utf8               args
      #14 = Utf8               [Ljava/lang/String;
      #15 = Utf8               StackMapTable
      #16 = Class              #14            //  "[Ljava/lang/String;"
      #17 = Class              #24            //  java/lang/Object
      #18 = Class              #25            //  java/lang/Throwable
      #19 = Utf8               m
      #20 = Utf8               SourceFile
      #21 = Utf8               Synchronized.java
      #22 = NameAndType        #4:#5          //  "<init>":()V
      #23 = Utf8               com/baidu/nuomi/concurrent/Synchronized
      #24 = Utf8               java/lang/Object
      #25 = Utf8               java/lang/Throwable
    {
      public com.baidu.nuomi.concurrent.Synchronized();
        flags: ACC_PUBLIC
        Code:
          stack=1, locals=1, args_size=1
             0: aload_0       
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: return        
          LineNumberTable:
            line 6: 0
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0       5     0  this   Lcom/baidu/nuomi/concurrent/Synchronized;
    
      public static void main(java.lang.String[]);
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=3, args_size=1
             0: ldc_w         #2                  // class com/baidu/nuomi/concurrent/Synchronized
             3: dup           
             4: astore_1      
             5: monitorenter  
             6: aload_1       
             7: monitorexit   
             8: goto          16
            11: astore_2      
            12: aload_1       
            13: monitorexit   
            14: aload_2       
            15: athrow        
            16: return        
          Exception table:
             from    to  target type
                 6     8    11   any
                11    14    11   any
          LineNumberTable:
            line 8: 0
            line 10: 6
            line 11: 16
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      17     0  args   [Ljava/lang/String;
          StackMapTable: number_of_entries = 2
               frame_type = 255 /* full_frame */
              offset_delta = 11
              locals = [ class "[Ljava/lang/String;", class java/lang/Object ]
              stack = [ class java/lang/Throwable ]
               frame_type = 250 /* chop */
              offset_delta = 4
    
    
      public static synchronized void m();
        flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
        Code:
          stack=0, locals=0, args_size=0
             0: return        
          LineNumberTable:
            line 12: 0
    }

    分析一下synchronized关键字的实现细节。

    上面class信息中,对于同步块的实现使用了

    monitorenter  和   monitorexit

    指令。而同步方法则是依靠方法修饰符上的

    ACC_SYNCHRONIZED

    来完成的。

    无论哪种方式,其本质是对一个对象的监视器进行获取,而这个获取的过程是排他的,也就是同一时刻只能有一个线程获取到由synchronized所保护对象的监视器。

    任意一个对象都拥有自己的监视器,当这个对象由同步块或者这个对象的同步方法调用时,执行方法的线程必须先获取到该对象的监视器才能进入同步块或者同步方法,而没有获取到监视器(执行该方法)的线程将会被阻塞在同步块和同步方法的入口处,进入BLOCKED状态。

  • 相关阅读:
    scroller,,list里面滚动到最后,,再添加10条数据
    Egret ,dataGroup,,,tabBar,,,List的区别
    自我回答,问题3:Scroller的属性 scrollPolicyV怎么无效呢,,也就是 scrollPolicyV设置为on,但是并没有显示滚动条
    自我回答,问题2:比如有个历史记录,,然后左边有个按钮btnleft,,右边有个按钮btnright,点击对应按钮,,就会有对应历史记录推进,或者后退
    自我回答,问题1:八个按钮(btn0-btn8),,下面有加分8个bitmap(bitmap0-8),,点击按钮对应有bitmap的值+=1
    js生成 1-100 不重复随机数
    laravel 的passport Oauth 认证登录请求 的 oauth_token 重置
    phpunit 测试指定目录下的测试类
    [SymfonyComponentDebugExceptionFatalThrowableError] Class 'Dingo' not found
    laravel 观察器 模型绑定 方法的关系
  • 原文地址:https://www.cnblogs.com/sonofelice/p/5595827.html
Copyright © 2011-2022 走看看