How to Improve the Performance of Java locks (1)

Source: Internet
Author: User

How to Improve the Performance of Java locks (1)

We try our best to find a solution to the problems encountered by our products, but I will share with you several common technologies in this article, these technologies include separating locks, parallel data structures, protecting data rather than code, and narrowing down the scope of the lock. These technologies enable us to detect deadlocks without any tools.

The lock is not the root cause of the problem, but the competition between locks is

When you encounter performance problems in multi-threaded code, you usually complain about the lock problem. After all, the lock will reduce the running speed of the program and its low scalability is well known. Therefore, if you begin to optimize the Code with this "Common Sense", the result may be annoying concurrency problems later.

Therefore, it is important to understand the differences between a competitive lock and a non-competitive lock. Lock contention is triggered when a thread tries to enter the synchronization block or method being executed by another thread. This thread will be forced to enter the waiting state until the first thread executes the synchronization block and has released the monitor. When only one thread tries to execute the synchronized code area at a time, the lock will remain non-competitive.

In fact, in non-competitive scenarios and most applications, JVM has optimized synchronization. Non-competitive locks do not incur any additional overhead during execution. Therefore, you should not complain about the lock due to performance issues, but should complain about the lock competition. With this understanding, let's look at what we can do to reduce the possibility of competition or reduce the duration of competition.

Protect data, not code

A quick way to solve the thread security problem is to lock the accessibility of the entire method. In the following example, we try to create an online poker game server using this method:

 
 
  1. class GameServer { 
  2.  
  3. public Map<> tables = new HashMap>(); 
  4.  
  5. public synchronized void join(Player player, Table table) { 
  6.  
  7. if (player.getAccountBalance() > table.getLimit()) { 
  8.  
  9. List tablePlayers = tables.get(table.getId()); 
  10.  
  11. if (tablePlayers.size() < 9) { 
  12.  
  13. tablePlayers.add(player); 
  14.  
  15.  
  16.  
  17.  
  18. public synchronized void leave(Player player, Table table) {/*body skipped for brevity*/} 
  19.  
  20. public synchronized void createTable() {/*body skipped for brevity*/} 
  21.  
  22. public synchronized void destroyTable(Table table) {/*body skipped for brevity*/} 
  23.  

The author's intention is good-when a new player joins the card table, make sure that the number of players on the card table does not exceed the total number of players that the card table can accommodate.

However, this solution actually requires control of the player's entry to the card table at any time, even when the server's access volume is small, threads waiting for lock release are destined to frequently trigger system competition events. Locked blocks that include checks on account balances and card table restrictions may greatly increase the overhead of calling operations, which will undoubtedly increase the possibility and duration of competition.

The first step is to ensure that we protect the data, rather than moving from the method declaration to the synchronous declaration in the method body. For the simple example above, it may not change much. However, we need to consider the interface of the entire game service, rather than simply a join () method.

 
 
  1. class GameServer { 
  2.  
  3. public Map> tables = new HashMap>(); 
  4.  
  5. public void join(Player player, Table table) { 
  6.  
  7. synchronized (tables) { 
  8.  
  9. if (player.getAccountBalance() > table.getLimit()) { 
  10.  
  11. List tablePlayers = tables.get(table.getId()); 
  12.  
  13. if (tablePlayers.size() < 9) { 
  14.  
  15. tablePlayers.add(player); 
  16.  
  17.  
  18.  
  19.  
  20.  
  21. public void leave(Player player, Table table) {/* body skipped for brevity */} 
  22.  
  23. public void createTable() {/* body skipped for brevity */} 
  24.  
  25. public void destroyTable(Table table) {/* body skipped for brevity */} 
  26.  

It may have been a small change, but it affects the behavior of the entire class. The previous synchronization method locks the entire GameServer instance at any time, and then competes with gamers who attempt to leave the table at the same time. Moving the lock from the method declaration to the method body will delay the loading of the lock, thus reducing the possibility of lock competition.


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.