Java concurrent programming practice - shared object

sponsored links
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.

Visibility


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)
                Thread.yield();
                 // Here you may output 0, may never output  
            System.out.println(number);
        }
    }
 
    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:

@NotThreadSafe
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)
        countSomeSheep();


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) {
        source.registerListener(
            new EventListener() {// Prematurely exposed  this
                public void onEvent(Event e) {
                    doSomething(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) {
                doSomething(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  
        source.registerListener(safe.listener);
        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.

Immutability


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:

@Immutable
public final class ThreeStooges {
    private final Set<String> stooges = new HashSet<String>();
    public ThreeStooges() {
        stooges.add("Moe");
    }
    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.

@Immutable
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;
        else
            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

@ThreadSafe
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;
  • del.icio.us
  • StumbleUpon
  • Digg
  • TwitThis
  • Mixx
  • Technorati
  • Facebook
  • NewsVine
  • Reddit
  • Google
  • LinkedIn
  • YahooMyWeb

Related Posts of Java concurrent programming practice - shared object

  • hibernate query cache

    hibernate query cache Query cache is cached result set of common property On the entity object cache only the result set id Query cache life cycle, when the associated table happened to amend, then the query cache of the life cycle of The End Query cache

  • hibernate how to store binary, image and other major fields.

    model categories: reportByte binary type for the database fields. public class PfReportStyle implements java.io.Serializable , Cloneable { // Fields /** * */ private static final long serialVersionUID = 1L; private Long id; private byte[] reportByte; // C

  • hibernate study of the second

    Persistence of three main points: 1, a statement for persistent fields accessors (accessors) and whether the variable signs (mutators) Property statement is not necessarily required for the public's. Hibernate can be default, protected or private ...

  • Real design pattern

    I hate the thought of the time to teach some provide a lot of code, because I think the thought process of acceptance should be a pleasure to read as a novel process, rather than spend a lot of brain power for a certain process details And this world ...

  • hibernate (jpa) composite primary key annotation statement Ways

    In the design of the database tables are designed with a composite primary key of the table, that table's record by more than one field joint identification, such as: Table CREATE TABLE TB_HOUR_DATA ( STAT_DATE DATE NOT NULL, PATH_ID NUMBER(20) NOT NULL,

  • log4j easy application in java

    JAVA development, frequently used the log output, in a so-called most of the software company will have its own set of configuration style, re-read the configuration file to initialize property of the log, it will be good, but sometimes may not need to fu

  • jboss ejb3 Message Driven Bean

    Super Medium ejb hate. . . . . . . . . . . . . . . . . . . ================================================ To configure a Message Driven Bean in a different application server parameters are not the same. Currently only passed the test jboss. Message Dri

  • [Reprint] Java professionals required books and list of sites

    Concurrent Programming in Java: Design Principles and Patterns (Doug Lea) Concurrent Programming in Java: Design Principles and Patterns, 2nd edition (Doug Lea; Addison-Wesley, 1999 years) Java Concurrent Programming - Design principles and patterns (seco

  • hibernate generic generic DAO

    package org.lzpeng.dao; import java.io.Serializable; import java.util.List; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.criterion.Criterion; import org.springside.modules.orm.hibernate.Page; /** * * @version 2009-1-10 *

  • First Hibernate Example

    Curd a simple example. Source does not contain the dependent libraries, or playing too much of the package. PO object Note: One must have the default constructor 2 non-final modified. Otherwise useless lazy loading. UserDAOImpl category code, and other co

blog comments powered by Disqus
Recent
Recent Entries
Tag Cloud
Random Entries