Tips for using locks efficiently in Java)

Source: Internet
Author: User
As a mechanism used to protect the critical section, lock is widely used in multi-threaded programs. Both the synchronized keyword in the Java language and the reentrantlock in the Java. util. Concurrent package are powerful tools in the hands of multithreaded application developers. However, powerful tools are usually a double-edged sword. Excessive or incorrect use of locks can lead to a reduction in the performance of multi-threaded applications. This problem is becoming increasingly apparent today when the multi-core platform becomes mainstream.

Competitive locks are the main cause of performance bottlenecks in multi-threaded applications

Distinguishing between a competitive lock and a non-competitive lock is very important to the performance. If a lock is used by only one thread from start to end, the JVM has the ability to optimize most of the losses it brings. If a lock has been used by multiple threads but only one thread tries to obtain the lock at any time, the overhead of the lock will be higher. The above two locks are called non-competitive locks. The most serious impact on performance occurs when multiple threads attempt to obtain the lock at the same time. In this case, the JVM cannot be optimized, and switching from user to kernel usually occurs. Modern JVM has made a lot of Optimizations to non-competitive locks so that it will hardly affect performance. The following are common optimizations.

* If a lock object can only be accessed by the current thread, other threads cannot obtain the lock and synchronize it. Therefore, JVM can remove requests for the lock.
* Escape analysis can identify whether local object references are exposed in the heap. If not, you can change the local object reference to a local thread ).
* The compiler can also perform lock coarsening ). Merge adjacent synchronized blocks with the same locks to reduce the acquisition and release of unnecessary locks.

Therefore, do not worry about the overhead caused by non-competitive locks. Pay attention to the performance optimization in the key zones that actually have a lock competition.

Methods To reduce lock Competition

Many developers try to minimize the use of locks because they are worried about performance loss caused by synchronization, and even do not use lock protection for some critical zones that seem to have an extremely low probability of errors. This will not improve performance, but will introduce debugging errors that are difficult to debug. These errors are usually very low in probability and are difficult to reproduce.

Therefore, to ensure the correctness of the program, the first step to solve the performance loss caused by the synchronization belt is not to remove the lock, but to reduce the lock competition. Generally, there are three ways to reduce the lock competition: reduce the lock holding time, reduce the frequency of the Request lock, or use other coordination mechanisms to replace the exclusive lock. These three methods contain many best practices, which are described in the following sections.

Avoid time consumption calculation in the critical section

Generally, the technology that turns code into thread-safe is to add a "big lock" to the entire function ". For example, in Java, declare the entire method as synchronized. However, what we need to protect is the sharing status of the object, not the code.

Long lock hold limits the scalability of applications. Brian Goetz mentioned in Java concurrency in practice that if an operation holds a lock for more than 2 milliseconds and each operation requires the lock, no matter how many idle processors are there, the throughput of an application cannot exceed 500 operations per second. If you can reduce the lock holding time to 1 millisecond, you can increase the lock-related throughput to 1000 operations per second. In fact, here We conservatively estimate the overhead of holding the lock for a long time because it does not involve the overhead brought about by the competition of computing locks. For example, CPU time is wasted because of busy waiting and line switching caused by failed lock acquisition. The most effective way to reduce the possibility of lock competition is to shorten the lock holding time as much as possible. This can be achieved by removing the code that does not require lock protection from the synchronization block, especially those that are expensive and potentially congested, such as I/O operations.

In example 1, we use JlM (Java lock Monitor) to view the lock usage in Java. Foo1 uses synchronized to protect the entire function. foo2 only protects the variable maph. Aver_htm shows the holding time of each lock. We can see that after the irrelevant statement is removed from the synchronization block, the lock holding time is reduced, and the program execution time is also shortened.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.