Introduction to threading Optimization in-java 6
Sun, IBM, Bea, and others have spent a great deal of effort on the implementation of their Java 6 virtual machines to optimize lock management and synchronization. Such features as biased locks (biased locking), lock coarsening (lock coarsening), lock ellipsis from Escape (escape) analysis, adaptive spin locks (adaptive spinning), Increases concurrency efficiency by sharing data more efficiently among application threads. While these features are both mature and interesting, the question is: are their promises really achievable? In this two-part article, I'll explore these features one by one, and try to answer questions about performance with the help of a single thread benchmark.
Pessimistic lock model
The Java-supported lock model is definitely a pessimistic lock (in fact, most line threading are). If two or more threads interfere with each other when using data, this minimal risk forces us to use very strict measures to prevent this from happening--using locks. Studies have shown, however, that locks are rarely occupied. In other words, a thread that accesses a lock rarely has to wait to get it. But the action of requesting a lock triggers a series of actions that can cause serious overhead, which is unavoidable.
We do have other options, indeed. For example, consider the use of thread-safe stringbuffer. Ask yourself: Have you ever known that it can only be accessed by a thread safely, or insist on using StringBuffer, why not StringBuilder instead?
Knowing that most locks are not competitive, or that the fact that there is little competition, is not very useful to us because even two of threads accessing the same data are very low in probability, forcing us to use locks to protect the data being accessed through synchronization. "Do we really need a lock?" "This problem can be finally answered only after we have observed the lock in the context of the runtime environment." To find the answer to the problem, the JVM's developers have started doing a lot of experimental work on hotspot and JIT. Now, we've got an adaptive spin lock, a bias lock, and two ways of locking (lock elimination)--lock coarsening and lock elision. Before we start benchmarking, take the time to review these features to help you understand how they work.
Escape analysis-Simple analysis of lock ellipsis (escape Analysis-lock Elision explained)
An escape analysis is an analysis of the scope of all references in a running application. Escape analysis is an integral part of the hotspot analysis work. If hotspot (through escape analysis) is able to determine that multiple references to an object are limited to local space, and that none of these references "escape" to the space, then hotspot will require a series of run-time optimizations by the JIT. One of the optimizations is lock elision. If a reference to a lock is restricted to local space, the lock is only accessed by the thread that created the lock. In this condition, the values in the synchronization block will never compete. This means that we will never really need this lock, it can be safely ignored. Consider the following methods:
public String concatBuffer(String s1, String s2, String s3) {,
StringBuffer sb = new StringBuffer();
sb.append(s1);
sb.append(s2);
sb.append(s3);
return sb.toString();
}
Figure 1. Use a local StringBuffer connection string
If we look at the variable SB, we will soon find that it is only confined to the Concatbuffer method. Further, all references to SB will never "escape" from the Concatbuffer method, that is, the method that declares it. Therefore, other threads cannot access SB copy of the current thread. According to the knowledge we have just introduced, we know that locks used to protect SB can be ignored.
On the surface, lock ellipsis seems to allow us to write thread-safe code without having to endure the burden of synchronization, provided that synchronization is indeed superfluous. Does locking ellipsis really work? This is the question that we will answer in the benchmark test that follows.
Simple analysis of deflection lock (biased locking explained)
Most locks, in their lifecycle, are never accessed by more than one thread. Even in rare cases, multiple lines Chengjian shared data, and locks do not compete. To understand the advantages of the lock, we first need to review how to acquire the lock (monitor).
The process of acquiring a lock is divided into two parts. First, you need to get a contract. Once you get the contract, you're free to get the lock. In order to obtain this contract, the thread must execute a costly atomic instruction. Releasing the lock will also release the contract. According to our observations, we seem to need to optimize access to some locks, such as the synchronized block code that the thread executes in a loop body. One way to optimize this is to make the lock bold to include the entire loop. This way, the thread accesses the lock only once, without having to access it every time it enters the loop. However, this is not a good solution because it may hinder legitimate access by other threads. There is also a more reasonable scheme for locking the lock toward the thread that executes the loop.
Leaning the lock on a thread means that the thread does not need to release the lock's contract. Therefore, subsequent acquisition of the lock can be less expensive. If another thread is trying to acquire a lock, then the loop thread can only release the contract. The Java 6 Hotspot/jit is optimized for preference locks by default.