jvm相关:synchronized实现与扩展

定义

Synchronization

Synchronization in the Java Virtual Machine is implemented by monitor entry and exit, either explicitly (by use of the monitorenter and monitorexit instructions) or implicitly (by the method invocation and return instructions).

Java虚拟机中的同步是通过监视入口和出口实现的,可以是显式的(通过使用monitorenter和monitorexit指令),也可以是隐式的(通过方法调用和返回指令)。

For code written in the Java programming language, perhaps the most common form of synchronization is the synchronized method. A synchronized method is not normally implemented using monitorenter and monitorexit. Rather, it is simply distinguished in the run-time constant pool by the ACC_SYNCHRONIZED flag, which is checked by the method invocation instructions (§2.11.10).

对于用Java编程语言编写的代码,最常见的同步形式可能是synchronized方法。同步方法通常不使用monitorenter和monitorexit实现。相反,它只是通过ACC_SYNCHRONIZED标志在运行时常量池中进行区分,该标志由方法调用指令(2.11.10)检查。

The monitorenter and monitorexit instructions enable the compilation of synchronized statements.

monitorenter monitorexit 指令可以由synchronized 语句编译生成。

The compiler ensures that at any method invocation completion, a monitorexit instruction will have been executed for each monitorenter instruction executed since the method invocation. This is the case whether the method invocation completes normally (§2.6.4) or abruptly (§2.6.5). To enforce proper pairing of monitorenter and monitorexit instructions on abrupt method invocation completion, the compiler generates exception handlers (§2.10) that will match any exception and whose associated code executes the necessary monitorexit instructions.

编译器确保在任何方法调用完成时,对于自方法调用以来执行的每个monitorenter指令,都会执行monitorexit指令。方法调用是正常完成(2.6.4)还是突然完成(2.6.5)。为了在突然的方法调用完成时强制执行monitorenter和monitorexit指令的正确配对,编译器生成异常处理程序(2.10),它将匹配任何异常,其相关代码将执行必要的monitorexit指令。

The Java Virtual Machine supports synchronization of both methods and sequences of instructions within a method by a single synchronization construct: the monitor.

Java虚拟机通过一个同步结构(监视器)支持方法中的方法和指令序列的同步。

Method-level synchronization is performed implicitly, as part of method invocation and return (§2.11.8). A synchronized method is distinguished in the run-time constant pool's method_info structure (§4.6) by the ACC_SYNCHRONIZED flag, which is checked by the method invocation instructions. When invoking a method for which ACC_SYNCHRONIZED is set, the executing thread enters a monitor, invokes the method itself, and exits the monitor whether the method invocation completes normally or abruptly. During the time the executing thread owns the monitor, no other thread may enter it. If an exception is thrown during invocation of the synchronized method and the synchronized method does not handle the exception, the monitor for the method is automatically exited before the exception is rethrown out of the synchronized method.

方法级同步是隐式执行的,作为方法调用和返回的一部分(第2.18.8节)。 同步方法在运行时常量池的method_info结构(第4.6节)中由ACC_SYNCHRONIZED标志区分,该标志由方法调用指令检查。 当调用设置了ACC_SYNCHRONIZED的方法时,执行线程进入监视器,调用方法本身,并退出监视器,方法调用是正常还是突然完成。 在执行线程拥有监视器期间,没有其他线程可以输入它。 如果在调用synchronized方法期间抛出异常并且synchronized方法不处理异常,则在异步从同步方法中重新抛出之前,将自动退出该方法的监视器。

Synchronization of sequences of instructions is typically used to encode the synchronized block of the Java programming language. The Java Virtual Machine supplies the monitorenter and monitorexit instructions to support such language constructs. Proper implementation of synchronized blocks requires cooperation from a compiler targeting the Java Virtual Machine (§3.14).

指令序列的同步通常用于编码Java编程语言的同步块。 Java虚拟机提供monitorenter和monitorexit指令以支持此类语言结构。 正确实现同步块需要来自针对Java虚拟机(第3.14节)的编译器的合作。

Structured locking is the situation when, during a method invocation, every exit on a given monitor matches a preceding entry on that monitor. Since there is no assurance that all code submitted to the Java Virtual Machine will perform structured locking, implementations of the Java Virtual Machine are permitted but not required to enforce both of the following two rules guaranteeing structured locking. Let T be a thread and M be a monitor. Then:

  1. The number of monitor entries performed by T on M during a method invocation must equal the number of monitor exits performed by T on M during the method invocation whether the method invocation completes normally or abruptly.

  2. At no point during a method invocation may the number of monitor exits performed by T on M since the method invocation exceed the number of monitor entries performed by T on M since the method invocation.

结构化锁定是指在方法调用期间,给定监视器上的每个出口与该监视器上的前一个条目匹配时的情况。由于无法保证提交给Java虚拟机的所有代码都将执行结构化锁定,因此允许Java虚拟机实现,但不需要强制执行以下两个保证结构化锁定的规则。设T为线程,M为监视器。然后:

  1. 在方法调用期间由T在M上执行的监视器条目的数量必须等于方法调用期间由T在M上执行的监视器退出的数量,无论方法调用是正常还是突然完成。
  2. 在方法调用期间,在方法调用期间,由于方法调用,由T在M上执行的监视器退出的数量可能超过自从方法调用以来由T在M上执行的监视器条目的数量。

Note that the monitor entry and exit automatically performed by the Java Virtual Machine when invoking  synchronized method are considered to occur during the calling method's invocation.

请注意,在调用方法的调用期间,会考虑在调用synchronized方法时由Java虚拟机自动执行的监视器进入和退出。

Methods

Each method, including each instance initialization method (§2.9) and the class or interface initialization method (§2.9), is described by a method_info structure. No two methods in one class file may have the same name and descriptor (§4.3.3).

每个方法(包括每个实例初始化方法(第2.9节)和类或接口初始化方法(第2.9节))都由method_info结构描述。一个类文件中没有两个方法可能具有相同的名称和描述符(第4.3.3节)。

The structure has the following format:

method_info {
    u2             access_flags;
    u2             name_index;
    u2             descriptor_index;
    u2             attributes_count;
    attribute_info attributes[attributes_count];
}

The items of the method_info structure are as follows:

access_flags

The value of the access_flags item is a mask of flags used to denote access permission to and properties of this method. The interpretation of each flag, when set, is as shown in Table 4.5.

Table 4.5. Method access and property flags


Flag Name	        Value	Interpretation
ACC_PUBLIC	        0x0001	Declared public; may be accessed from outside its package.
ACC_PRIVATE	        0x0002	Declared private; accessible only within the defining class.
ACC_PROTECTED	    0x0004	Declared protected; may be accessed within subclasses.
ACC_STATIC	        0x0008	Declared static.
ACC_FINAL	        0x0010	Declared final; must not be overridden (§5.4.5).
ACC_SYNCHRONIZED	0x0020	Declared synchronized; invocation is wrapped by a monitor use.
ACC_BRIDGE	        0x0040	A bridge method, generated by the compiler.
ACC_VARARGS	        0x0080	Declared with variable number of arguments.
ACC_NATIVE	        0x0100	Declared native; implemented in a language other than Java.
ACC_ABSTRACT	    0x0400	Declared abstract; no implementation is provided.
ACC_STRICT	        0x0800	Declared strictfp; floating-point mode is FP-strict.
ACC_SYNTHETIC	    0x1000	Declared synthetic; not present in the source code.

            The ACC_VARARGS flag indicates that this method takes a variable number of arguments at the source code level. A method declared to take a variable number of arguments must be compiled with the ACC_VARARGS flag set to 1. All other methods must be compiled with the ACC_VARARGS flag set to 0.

            ACC_VARARGS标志指示此方法在源代码级别采用可变数量的参数。声明采用可变数量参数的方法必须ACC_VARARGS标志设置为1的情况下进行编译。所有其他方法必须在ACC_VARARGS标志设置为0的情况下编译。

            The ACC_BRIDGE flag is used to indicate a bridge method generated by a Java compiler.

             ACC_BRIDGE标志用于指示Java编译器生成的桥接方法。

            A method may be marked with the ACC_SYNTHETIC flag to indicate that it was generated by a compiler and does not appear in source code, unless it is one of the methods named in §4.7.8.

            可以用ACC_SYNTHETIC标志标记方法,以指示它是由编译器生成的,并且不出现在源代码中,除非它是§4.7.8中命名的方法之一。

            Methods of classes may set any of the flags in Table 4.5. However, a specific method of a class may have at most one of its ACC_PRIVATEACC_PROTECTED and ACC_PUBLIC flags set (JLS §8.4.3). If a specific method has its ACC_ABSTRACT flag set, it must not have any of its ACC_FINALACC_NATIVEACC_PRIVATEACC_STATICACC_STRICT or ACC_SYNCHRONIZED flags set (JLS §8.4.3.1, JLS §8.4.3.3, JLS §8.4.3.4).

            类的方法可以设置表4.5中的任何标志。但是,类的特定方法最多可以设置一个ACC_PRIVATE,ACC_PROTECTED和ACC_PUBLIC标志(JLS§8.4.3)。如果特定方法设置了ACC_ABSTRACT标志,则它不能设置任何ACC_FINAL,ACC_NATIVE,ACC_PRIVATE,ACC_STATIC,ACC_STRICT或ACC_SYNCHRONIZED标志(JLS§8.4.3.1,JLS§8.4.3.3,JLS§8.4.3.4)。

            All interface methods must have their ACC_ABSTRACT and ACC_PUBLIC flags set; they may have their  ACC_VARARGSACC_BRIDGE and ACC_SYNTHETIC flags set and must not have any of the other flags in Table 4.5 set (JLS §9.4).

           所有接口方法必须设置其ACC_ABSTRACT和ACC_PUBLIC标志;它们可能设置了ACC_VARARGS,ACC_BRIDGE和ACC_SYNTHETIC标志,并且必须没有表4.5中的任何其他标志(JLS§9.4)。

           A specific instance initialization method (§2.9) may have at most one of its ACC_PRIVATEACC_PROTECTED, and ACC_PUBLIC flags set, and may also have its ACC_STRICTACC_VARARGS and ACC_SYNTHETIC flags set, but must not have any of the other flags in Table 4.5 set.

          特定实例初始化方法(第2.9节)最多可设置一个ACC_PRIVATE,ACC_PROTECTED和ACC_PUBLIC标志,并且还可以设置其ACC_STRICT,ACC_VARARGS和ACC_SYNTHETIC标志,但不得具有表4.5中的任何其他标志。

         Class and interface initialization methods (§2.9) are called implicitly by the Java Virtual Machine. The value of their access_flags item is ignored except for the setting of the ACC_STRICT flag.

          类和接口初始化方法(第2.9节)由Java虚拟机隐式调用。 除了ACC_STRICT标志的设置外,它们的access_flags项的值被忽略。

          All bits of the access_flags item not assigned in Table 4.5 are reserved for future use. They should be set to zero in generated class files and should be ignored by Java Virtual Machine implementations.

         表4.5中未分配的access_flags项的所有位都保留供将来使用。它们应该在生成的类文件中设置为零,并且应该被Java虚拟机实现忽略。

name_index

         The value of the name_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure representing either one of the special method names (§2.9<init> or <clinit>, or a valid unqualified name (§4.2.2) denoting a method.

         name_index项的值必须是constant_pool表的有效索引。该索引处的constant_pool条目必须是CONSTANT_Utf8_info(§4.4.7)结构,表示特殊方法名称之一(§2.9)<init>或<clinit>,或者表示一个有效非限定名称(§4.2.2)方法。

descriptor_index

        The value of the descriptor_index item must be a valid index into the constant_pool table. The constant_pool entry at that index must be a CONSTANT_Utf8_info (§4.4.7) structure representing a valid method descriptor (§4.3.3).

        descriptor_index项的值必须是constant_pool表的有效索引。该索引处的constant_pool条目必须是表示有效方法描述符(第4.3.3节)的CONSTANT_Utf8_info(§4.4.7)结构。

       A future edition of this specification may require that the last parameter descriptor of the method descriptor is an array type if the ACC_VARARGS flag is set in the access_flags item.

      如果在access_flags项中设置了ACC_VARARGS标志,则此规范的未来版本可能要求方法描述符的最后一个参数描述符是数组类型。

attributes_count

      The value of the attributes_count item indicates the number of additional attributes (§4.7) of this method.

      attributes_count项的值表示此方法的附加属性数(第4.7节)。

attributes[]

       Each value of the attributes table must be an attribute structure (§4.7). A method can have any number of optional attributes associated with it.

       属性表的每个值必须是属性结构(第4.7节)。方法可以具有与之关联的任意数量的可选属性。

      The attributes defined by this specification as appearing in the attributes table of a method_info structure are the Code (§4.7.3), Exceptions (§4.7.5), Synthetic (§4.7.8), Signature (§4.7.9), Deprecated (§4.7.15), RuntimeVisibleAnnotations (§4.7.16), RuntimeInvisibleAnnotations (§4.7.17), RuntimeVisibleParameterAnnotations (§4.7.18), RuntimeInvisibleParameterAnnotations (§4.7.19), and AnnotationDefault (§4.7.20) attributes.

       本规范定义的属性出现在method_info结构的属性表中的是Code(§4.7.3),Exceptions(§4.7.5),Synthetic(§4.7.8),Signature(§4.7.9),不推荐使用(§4.7.15),RuntimeVisibleAnnotations(§4.7.16),RuntimeInvisibleAnnotations(§4.7.17),RuntimeVisibleParameterAnnotations(§4.7.18),RuntimeInvisibleParameterAnnotations(§4.7.19)和AnnotationDefault(§4.7.20)属性。

        A Java Virtual Machine implementation must recognize and correctly read Code (§4.7.3) and Exceptions (§4.7.5) attributes found in the attributes table of a method_info structure. If a Java Virtual Machine implementation recognizes class files whose version number is 49.0 or above, it must recognize and correctly read Signature (§4.7.9), RuntimeVisibleAnnotations (§4.7.16), RuntimeInvisibleAnnotations (§4.7.17), RuntimeVisibleParameterAnnotations (§4.7.18), RuntimeInvisibleParameterAnnotations (§4.7.19) and AnnotationDefault (§4.7.20) attributes found in the attributes table of a method_info structure of a class file whose version number is 49.0 or above.

        Java虚拟机实现必须识别并正确读取method_info结构的attributes表中的Code(§4.7.3)和Exceptions(§4.7.5)属性。如果Java虚拟机实现识别版本号为49.0或更高的类文件,则它必须识别并正确读取Signature(§4.7.9),RuntimeVisibleAnnotations(§4.7.16),RuntimeInvisibleAnnotations(§4.7.17),RuntimeVisibleParameterAnnotations(§) 4.7.18),RuntimeInvisibleParameterAnnotations(§4.7.19)和AnnotationDefault(§4.7.20)属性,在版本号为49.0或更高的类文件的method_info结构的attributes表中找到。

        A Java Virtual Machine implementation is required to silently ignore any or all attributes in the attributes table of a method_info structure that it does not recognize. Attributes not defined in this specification are not allowed to affect the semantics of the class file, but only to provide additional descriptive information (§4.7.1).

       一个Java虚拟机实现需要静默忽略它无法识别的method_info结构的属性表中的任何或所有属性。没有在本章定义的属性不允许影响属性在类文件的语义,但仅允许提供其他描述性信息(第4.7.1节)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值