Java concurrent programming practice - shared object

synchronized is not the only atomic, but also has the memory visibility. We not only hope to avoid one thread modify the other threads are using the object's state and wish to ensure that when a thread changes the state of the object, other threads can really see the change. You can use the display simultaneously or use the built-in library of the synchronization mechanism to ensure the safety of the object.


In multi-threaded environment, the following procedure is true, when ready, number 42 is not necessarily because it does not use appropriate synchronization mechanism, there is no guarantee that the main thread is ready and the number of values written to the read thread is visible.

public class NoVisibility {
    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
            while (!ready)
                 // Here you may output 0, may never output

    public static void main(String[] args) {
        new ReaderThread().start();
        number = 42;
        ready = true;

May have two problems here, one program may have to maintain circulation, because the thread is for reading, ready for values may never be visible. Second, the input number is 0, which is caused because the reordering, the writing thread will be ready with the number from the working memory to write back to the main memory, in the absence of synchronization mechanism, the first number was ready to write this was the first is uncertain, that is to write them back to the main memory when the logical order of procedure order may be just the opposite, because under a single thread, as long as the reordering will not affect the results, it is permissible.

In the case of not using synchronization, the compiler, run the device, run-time sequencing may be entirely unexpected, in the absence of proper synchronization of multi-threaded programs, try to infer that "necessary" action in memory, you will always be a misjudgment.

Expired data

Above NoVisibility program multi-threaded environment may also be read to date data, such as ready as true, the write thread has been set to the value of field number 42, but it has not yet had time to work the new value from memory to write Back to the main memory before reading the thread already be ready to read out from the main memory, and then the value of the initial or default value of 0, this value is clearly a value has expired, because the number is now Barbara The value should be 42, not 0.

In the absence of synchronization is similar to the database to read data using READ_UNCOMMITTED (uncommitted read) isolation level, then you are more willing to exchange properties with accuracy.

In NoVisibility, the expiration data may cause it to print the error value, or the program can not terminate. Expired data may make the data object reference is more complex, such as chain pointers in the linked list implementation. Outdated data may lead to serious mistakes and confusion, such as unexpected exception, dirty data structures, error calculation and the infinite loop.

The following procedures become more sensitive to the expiration data: if a thread calls a set, but have not had time to write this new value back to main memory, while another thread is at this time call get, it may not see the update The data was:

public class MutableInteger {
    private int value;
    public int  get() { return value; }
    public void set(int value) { this.value = value; }

64-bit non-atomic operations

When a thread synchronization in the case without reading the variable, it may be a date value. But at least it can see a thread where a complete set of real values, rather than a void value. This security guarantee is called a minimum security.

Minimum of security applied to all variables, with one exception: no declaration for the volatile 64-bit numeric variable double and long. Java memory model provides access (read actions) and store (write action) action is atomic, but for non-volatile in the long and double variables, JVM allows 64-bit read-write-back operation is divided into two 32. If the read and write in a different thread, this reads a non-volatile type long on a thread may now be written in the high value of 32 and another thread to write the value of the lower 32 bits of the end of this long variable The value of the two threads from the combination of high and low values. Therefore, even if you do not care about expired data, but only in the multi-use shared thread Cheng Xu's, variable in the long and double variables also Keneng is unsafe, Chu Fei will they Sheng Ming Wei volatile Lei Xing, Huo Zhesuo Baohu up.

Lock and visibility

Built-in locks can be used to ensure that a thread in some predictable way to see the impact of another thread, the same as the following figure. When B and A Executive to monitor the same synchronization lock block, A block in the synchronization among everything done on the B are visible, if not synchronized, there is no such guarantee.
Java concurrent programming practice - shared object

Not only on the synchronization and mutual exclusion lock, and it is visible on the memory. To ensure that all threads can see the shared variable becomes the latest value of reading and writing thread must use public locks for synchronization.

volatile variable

volatile is a weak form of synchronization, it ensures that updates a variable in a predictable manner to the other thread. When a field is declared volatile type, the compiler and run-time monitors this variable: it is shared, but it will not operate together with other memory operations to be re-sorted. volatile variable will not be cached in the registers or other processor in the object cache hidden place, so, reading a volatile type of variable, always returned by a thread to write the latest value.

Volatile variable read operation will not be locked, there would be no obstruction caused by the implementation of the thread, which makes the volatile variable relative to the sychronized, the only lightweight synchronization mechanism

volatile variable effects on the visibility is much higher than the value generated by the variable itself. Thread A writes to the volatile variable value, then thread B reads the variable, all write operations to the former A value of the variable visible in the B read this volatile variables, on the B is visible. Therefore, the visibility from the memory point of view, to write out of sync blocks as volatile variable read into the volatile variables as synchronized blocks. But we do not recommend over-reliance on volatile variables provide visibility. Because the dependent variable to control the volatile state of visibility of the code, than using the lock code more fragile, more difficult to understand.

Debugging Tip: For server applications, to ensure that both in the development phase or testing phase, when they start the JVM using the-server command-line options. server mode JVM Mode JVM than the client to perform more optimization, such as to not modify the loop variable raised to the external loop; in the development environment (client mode JVM) code that can work, may be deployment environment (server mode JVM) to fail. For example: For example, the following procedure, if we forget to asleep variable declared as volatile, server mode JVM will work to enhance inspection asleep to the outer loop (turn it into an infinite loop), but the client mode JVM will not to do so. Development environment is far less than infinite loop of unlocking it to put a production environment arising from the overhead.

Example: the number of sheep.

volatile boolean asleep;
    while (!asleep)

volatile variable is of course easy, but there are restrictions, they are often identified as a complete break, marking the state of use, such as the above proceedings asleep variables. Despite the volatile can be used to label other types of state information, but decided to do so before you take extra care to not like the semantics of volatile to use from the increase in operating (i + +) atomization.

Locking can guarantee visibility and atomicity; volatile variable can only be guaranteed visibility.

Only meet all the following criteria, you can use volatile variables:

1, write variable does not depend on the current value of the variable; or to be able to ensure that only one thread modify the value of a variable;

2, variables and other state variables do not need to participate in the same constraints;

3, and the visit variable, there is no other reason to lock.

Release and escape of the object

Release of an object means that it can be outside the scope of the code currently used. Example, store a reference to where other code can access, in a non-proprietary method returns the reference, it can also be passed to the method of his class. In many cases, we need to ensure that objects and their internal state is not exposed, in other cases, the use for legitimate purposes, we do hope they release an object, then the security may be required to thread synchronization. If the internal state variables issued, it could jeopardize the encapsulation, and use the program difficult to maintain stability; if published object, it did not complete construction, as Wei Ji thread-safe. An object will be in when it is not yet ready to release, this is called escaping. The following is a look at how the escape of an object.

The most common way is to release an object reference to the object store to the public static field, any class, and the thread can see the field. initialize method instantiates a new instance of HashSet, and store it to knownSecrets by reference to published this example:

public static Set<Secret> knownSecrets;
public void initialize() {
    knownSecrets = new HashSet<Secret>();

Release an object will indirectly release other objects. If you join a Secret object collection knownSecrets, you would have released the object, because any code can loop through and get the new Secret object. Similarly, from the non-private method return a reference, but also made to return the object release, issued the following array contains the Island name, and this array is supposed to be private:

class UnsafeStates {
    private String[] states = new String[] {
        "AK", "AL" ...
    public String[] getStates() { return states; }

States will be released in this way problems, this will allow the escape of the internal variable of the data, please do not do this. Because the caller can modify any of its contents. In this example, the array of states have escaped the scope of its own, this is the private data of this fact has become public in the.

The final release of the internal state of the object and its release mechanism is an internal class instance. The following is implicitly allowed to escape this reference, please do not do this:

public class ThisEscape {
    public ThisEscape(EventSource source) {
            new EventListener() {// Prematurely exposed  this
                public void onEvent(Event e) {

Construction Safety Practice

Released from inside the object constructor, only an unfinished construction objects. Or even the last line in the constructor is a reference to this release. If this reference to escape in the constructor, this object is considered to be "not properly constructed," so do not let this reference to escape during the construction.

A reference to the construction period leading to escape this common mistake is in the constructor to create local, anonymous thread and start it or start a thread and show this to be passed in the past, this is unsafe, because the new thread their object the completion of construction can be seen before. In the constructor create a thread and not wrong, but best not to start it immediately, instead, to release a start method to start or initialize an object has a thread.

In addition, the constructor calls a method of covering the examples cited in the same result in this structure during the escape.

If you want to register the listener in the constructor, or start the thread, you can use a private constructor and a public factory method, thus avoiding the problem is not correct.

The following is the use of factory methods to prevent this reference period in the tectonic escape:

public class SafeListener {
    private final EventListener listener;

    private SafeListener() {// Private constructors
        listener = new EventListener() {
            public void onEvent(Event e) {

    // Use the static factory method for the security release object
    public static SafeListener newInstance(EventSource source) {
        SafeListener safe = new SafeListener();// Structure after the re-registration
        return safe;// Security release object

Local variables are thread-safe, as long as we do not escape them.

Use ThreadLocal to ensure the thread closed. Suppose you are a single-threaded application up to a multi-line environment, you can be sharing of global variables are converted to ThreadLocal type, This will ensure thread safety. Provided that the semantics is to allow global shared like this, if the application-level cache into a heap buffer thread, it will be worthless.


Can not simultaneously also meet the needs of transgender.

After the state can not be modified to create an object is called immutable objects. Immutable objects are inherently thread-safe. Their constant domain is created in the constructor. Given their status can not be modified, these constants will never change. So we can not change the object will always be thread safe.

Immutability does not simply mean that the object of fear are the domain types are declared as final, all fields are final type of object may still be variable, because the final field to get an object reference variable. Only meet the following conditions, an object is immutable:

1, which the state can not be modified after creation supplemented;

2, all fields are final type; and,

3, which is correctly created (created during the escape did not happen this reference).

Note, technically speaking, immutable domain object type not all declared as final, this is possible, String is this class. Design of this class depends on the object of benign (except malicious) data precision analysis of competitiveness, but also Java memory model on a deep understanding of, but do not themselves do so. Version 1.5 is in addition to the extraterritorial final type hash, but before this is not, therefore, can not be enhanced 1.5 version of the semantic change.

In a non-variable objects Di internal variability of the same song you can use the object to manage their condition, such as the following Dai Ma, Sui Ran Yu stooges yes variable, but it Manzu the Yi Shang three, so an immutable Duixiang:

public final class ThreeStooges {
    private final Set<String> stooges = new HashSet<String>();
    public ThreeStooges() {
    public boolean isStooge(String name) {
        return stooges.contains(name);

final field

final field can not be changed (although if the final point of the target domain can not be changed, this object can still be modified), but it is in the Java memory model also has a special meaning. ensure that before making final field of security possible to initialize the security object immutability without simultaneously being able to freely access and share.

As "all the fields declared as private, unless they need more visibility," as "all the fields declared as final type, unless they are variable," is also a good practice.

Example: Using the volatile release immutable objects

The following is an immutable object, into the (construction time pass into the parameter) out of (use) have a copy of the state. Because the BigInteger is immutable, so the direct use of Arrays.copyOf to be copied, if the guidelines state the object is not immutable objects, should not use this technology, because these states are outside the guidelines can be the object of modified, or if it can only use the new cloning technologies for deep copied.

class OneValueCache {
    private final BigInteger lastNumber;
    private final BigInteger[] lastFactors;

    public OneValueCache(BigInteger i,
                         BigInteger[] factors) {
        lastNumber  = i;
        lastFactors = Arrays.copyOf(factors, factors.length);

    public BigInteger[] getFactors(BigInteger i) {
        if (lastNumber == null || !lastNumber.equals(i))
            return null;
            return Arrays.copyOf(lastFactors, lastFactors.length);

The following have been released above the immutable object, which plays a key role in volatile, if not it can not be changed even if OneValueCache class

public class VolatileCachedFactorizer implements Servlet {
    private volatile OneValueCache cache =
        new OneValueCache(null, null);// Here is a security release  

    public void service(ServletRequest req, ServletResponse resp) {
        BigInteger i = extractFromRequest(req);
        BigInteger[] factors = cache.getFactors(i);
        if (factors == null) {
            factors = factor(i);
            // Because the cache is  volatile, So the latest values are immediately visible to other threads
            cache = new OneValueCache(i, factors);
        encodeIntoResponse(resp, factors);

Immutable object and initialize security

Java memory model, shared objects can not be changed to provide a specific guarantee of initialization safety, that object is fully initialized before it can be external references.

Even if released into the object reference does not use synchronization, immutable objects can still be safe to visit. To obtain such a security guarantee on initialization, it should meet all the non-denaturing conditions: the state can not modify all domain types are final and correct structure.

Immutable objects stay in sync in case of no additional security applied to any thread; even when they do not need to synchronize release.

Variable objects and security release

If an object is not immutable, it must be safe to release, are released in the thread and consumer thread must be synchronized. We must ensure that the consumer thread can see the object at that time in release state.

In order to safely release the object, object reference and the state of the object must be visible to other threads. Create the right conditions for an object can be safely released through the following:

1, through the static initializer initialize object reference;

2, its reference to the volatile storage domain or AtomicReference;

3, it stores a reference to the correct object created Final domain;

4, or a reference to it stored in the correct protection domain by the lock.

Thread-safe in the container provided thread-safe guarantee is in compliance with the last requirement.

Usually, the easiest and safest way to release a statically created object, is to use a static initializer:

public static Holder holder = new Holder (42);
Static initializer in class by the JVM implementation of the initial stage, due to internal synchronization JVM, the mechanism to ensure that the object is initialized in this way can be safely released.

Object variability and safety release

Post a necessary condition for an object depends on the variability of the object:

1, immutable objects can be released by any mechanism;

2, effective immutable object (that object itself is variable, but as long as the state is no longer making changes after the release) must be issued to security;

3, variable objects must be safe release, and must be thread-safe or locked protection;

分类:Java 时间:2010-06-08 人气:225
blog comments powered by Disqus


  • public static void main (String args []) parameters 2010-05-15

    String args [] is the main function of main parameters, namely array of strings. Using eclipse in the editing, right-click to run the Java files in the Run As option, select Run Configurations. Main class in the Project and complete the project, resp

  • Why public static void main (String args []){} 2010-11-06

    main () is a Java program entry, program execution is the beginning of this entry. Class is a class member, main () method must be public members. So that it can be called in the execution environment. main () method does not produce the object can b

  • 浅析C#中的Main(String[] args)参数输入问题 2014-07-20

    本篇文章主要是对C#中的Main(String[] args)参数输入问题进行了详细的介绍,需要的朋友可以过来参考下,希望对大家有所帮助 指定相关的测试代码 首先,写一个用于测试的关于Main(String[] args)参数输入有关的代码类,如下: using System; public class Hello { public static void Main(String[] args) { switch (args[0]) { case "老板": Console.Write

  • How the eclipse of the main the String [] args parameter passed, and then export it 2010-12-26

    How the eclipse of the main the String [] args parameter passed, and then export it? In the Run menu to find Open Run dialog opens Select Java Application in the program need to run Select the Arguments Tab Enter the parameters in the Programe Argume

  • String [] args = new String [] {sql.toString ()} 2011-06-29

    In this problem StringBuffer sql = new StringBuffer (); Which sql.toString results: 'Test User 1', 'male' String [] args = new String [] {sql.toString ()} args.length 1 results Obviously not what we need. Note: new String []{"","",&quo

  • Java String object, the classic problem of (new String ()) [switch] 2011-08-05

    Look at an example, the code is as follows: Java code public class Test { public static void main (String [] args) { String str = "abc"; String str1 = "abc"; String str2 = new String ("abc"); System.out.println (str == str1);

  • [Multi-threaded programming] profoundly expounded thread synchronization mechanism 2010-05-16

    The full text: Author: buaawhl We can run a variety of computer software programs. Each run of the program may include multiple independent threads running (Thread). Threads (Thread) is a stand-alone program, run t

  • public void testStatementAddBatch () public void testConnCommit () 2011-09-01

    public void testStatementAddBatch() { Connection conn = null; Statement stmt = null; try { conn = getDBConnectionMsSqlBySuperAdmin(); stmt = conn.createStatement(); for(int i = 0; i < 100; i++) { String sql = " sql " + i; stmt.addBatch(sql);

  • Remove the array from the specified character string and the formation of a new string array 2010-09-13

    Remove the array from the specified character string and the formation of a new string array, gcc compile. #include<stdio.h> #include<string.h> int main() { char ch1[]="askdaskaskdaskg",str[]=""; int i=0; while(ch1[i]!='\0'

  • Bash string processing (and Java control) - 3 to (string) variable assignment 2011-09-07

    Bash string processing (and Java control) - 3 to (string) variable assignment In Java Simple assignment of s = "Hello"; Once assigned to the case of several variables s1 = s2 = "Same"; Assigned an integer (the integer converted to stri

iOS 开发

Android 开发

Python 开发



PHP 开发

Ruby 开发






Javascript 开发

.NET 开发



Copyright (C), All Rights Reserved. 版权所有 闽ICP备15018612号

processed in 0.427 (s). 12 q(s)