[B] Three ways to ensure thread safety: [/b]
Do not access shared variables across threads
To make a shared variable the final type
To synchronize the operation of a shared variable
It's easier to design a class as thread-safe from the start than to fix it later.
Write multithreaded programs, first of all to ensure that it is correct, and then consider the performance.
Stateless or read-only objects are always thread-safe.
Do not expose a shared variable to a multithreaded environment (no synchronization or immutability protection)
Lazy loading in a multithreaded environment requires synchronous protection because lazy loading causes objects to be instantiated repeatedly
It is often unsafe to operate on variables of the numeric type of a volatile declaration (volatile can only guarantee visibility and cannot guarantee atomicity). See the volatile principles and techniques for a discussion of dirty data issues.
When a thread requests to obtain its own lock (nested use of the same lock), we call the lock a reentrant lock. In the jdk1.5 and contract package, a reentrant lock Java implementation-reentrantlock is provided.
Each shared variable should be protected by a uniquely determined lock. Create the same number of reentrantlock as the variables, so that they are responsible for the thread safety of each variable.
While reducing the range of synchronization blocks, you can improve system performance. However, in the case of atomicity, atomic operations cannot be decomposed into multiple synchronized blocks.
In the absence of synchronization, the sequence of instructions executed by the compiler and the processor runtime may be completely unexpected. The reason is that the compiler or processor reordered the instructions (reordering) in order to optimize its own execution efficiency.
When a thread reads a variable without synchronization, it may get an expiration value, but at least it can see a true value that the thread set at that time. Rather than the value of a vacuum. This safety guarantee, known as the minimum security (Out-of-thin-air safety)
When developing concurrent applications, this insecure approach is sometimes used in order to significantly increase the throughput and performance of the system. However, the numerical operation is still rejected.
Volatile variables can only guarantee visibility and cannot guarantee atomicity.
Certain time-consuming network operations or IO ensure that the lock is not occupied when executed.
Publish (publish) object, which means that it can be used by code outside the current scope. (pass-through) object escaping (escape), which refers to an object that is published when it is not yet ready.
Principle: In order to prevent escaping, the object must be fully constructed before it can be released (the best solution is to use synchronization)
This keyword refers to an object escaping
Example: In a constructor, the thread is opened and its own object this is passed into the thread, causing the reference to pass. At this point, when the constructor has not finished executing, the object escapes.
If necessary, use the threadlocal variable to ensure thread containment (the enclosing thread is often more secure, but to some extent, performance loss) Examples of closed objects are more common in actual use, such as the hibernate opensessioninview mechanism, The connection mechanism of JDBC.
A single Immutable object is often thread-safe (complex immutable objects need to ensure that their internal member variables are not variable) Good multithreaded programming habits are: Declare all fields as final unless they are mutable
Ensure that the publication of the shared variable is secure a, initialize the object through the static initializer (JLS 12.4.2, the JVM guarantees that the static initialization variable is synchronous) B, declare the object as volatile or use atomicreference C to ensure that the object is immutable D, To protect a reference or variable operation from a lock
To design a thread-safe class, you should include the basic elements: A, determine which variables are variable B, determine which are immutable variable C, and specify a policy for managing concurrent access to object state
Encapsulates the data inside the object and guarantees that access to the data is atomic. It is recommended to use the volatile JavaBean model or to construct a synchronized getter,setter.
Thread-Restrictive makes it easier to construct thread-safe classes, because when the state of a class is limited, it is not necessary to examine the complete program when it parses its thread security.
Writing concurrent programs requires more comments and a more complete description of the documentation.
When you need to subdivide the allocation of locks, using Java Monitor mode is better than using your own object's monitor lock. The former is more flexible.
Object target = new Object ();
External objects are used here as monitors, not this
Synchronized (target) {
Todo
}
For Java monitor pattern, the implementation of Reentrantlock is actually much easier to program concurrently. Functional, but also more powerful.
When designing concurrent programs, it is preferable to delegate shared variables to thread-safe classes, given the scalability and performance tradeoffs. It controls global concurrency access.
An iterator using a normal synchronization container (Vector, Hashtable) requires an external lock to guarantee its atomicity. The reason is that the iterator produced by the normal synchronization container is non-thread-safe.
In concurrent programming, the use of JDK concurrency containers (concurrenthashmap, Concurrentlinkedqueue, copyonwritearraylist ...) is preferred when container support is required.
Concurrenthashmap, an iterator for copyonwritearraylist concurrent containers, and a full range of size (), isEmpty () show weak consistency. They can only indicate a data state at the time of the container. The changes and modifications after the container cannot be fully responded to.
Use bounded queues, which block all read and write operations when the queue is full or empty. (A good solution for production-consumption) Blockqueue implementation has linkedblockingqueue and Arrayblockingqueue, the former is a linked list, variable operation is frequently preferred, the latter is an array, read operations are frequently preferred. Priorityblockingqueue is a priority-ordered blocking queue that can sort all placed elements (implementing the Comparator interface)
When a method, can throw interruptedexception, means that this method is a blocking method, if it is interrupted, will prematurely end the blocking state. When you invoke a blocking method, it also means that itself is called a blocking method, because you have to wait for the blocking method to return.
If the blocking method throws an interrupt exception, what we need to do is to throw it to the top, unless it is currently the level at which the exception needs to be caught. If the current method cannot throw interruptedexception, You can use the Thread.currentThread.interrupt () method to manually interrupt.
ArrayList how to ensure thread safety in Java