Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

An example Analysis of delayed Lock vs Synchronized in Java

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

What this article shares with you is an example analysis of delayed Lock vs Synchronized in Java. The editor thinks it is very practical, so I share it with you to learn. I hope you can get something after reading this article.

A few days ago, when I diagnosed some strange allocation problems during JIT compilation, I found that there was a problem with the allocation of java.util.concurrent.locks.ReentrantLock, but this only occurred under competitive conditions. (this is easy to prove, as long as you run a test program that establishes competition on Lock and specifies the-verbosegc parameter (similar to the program below).

An example is the output of GC when there is Lock competition:

[GC (Allocation Failure) 16384K-> 1400K (62976K), 0.0016854 secs] [GC (Allocation Failure) 17784K-> 1072K (62976K), 0.0011939 secs] [GC (Allocation Failure) 17456K-> 1040K (62976K), 0.0008452 secs] [GC (Allocation Failure) 17424K-> 1104K (62976K), 0.0008338 secs] [GC (Allocation Failure) 17488K-> 1056K (61952K), 0.0008799 secs] [GC (Allocation Failure) 17440K-> 1024K (61952K), 0.0010529 secs] [GC (Allocation Failure) 17408K-> 1161K (61952K) 0.0012381 secs] [GC (Allocation Failure) 17545K-> 1097K (61440K), 0.0004592 secs] [GC (Allocation Failure) 16969K-> 1129K (61952K), 0.0004500 secs] [GC (Allocation Failure) 17001K-> 1129K (61952K), 0.0003857 secs]

I wonder if it is necessary to clean up the space allocated on the Lock during garbage collection, in a highly competitive environment, will choose a worse synchronization strategy than the built-in 'synchronized'.

Of course, this question is more academic than any other issue. If you are really concerned about latency, you will find that you have never (or should never) have such a situation that requires so many thread locks. However, please continue to explore this question with me, because the process and results are very interesting.

Brief history: locks were introduced in Java 1.5 in 2004. Locks and other concurrent tools are born because of the urgent need for simple concurrent structures. Before that, you had to control concurrency through the built-in wait () and notify () methods of synchronized and Object.

ReentrantLock provides many better features than synchronized. Here are some examples:

Become unstructured-for example, not restricted by blocks or methods, allowing you to hold locks across multiple methods.

Polling lock

Timeout waiting for lock

Configure failure policy

But what role do they play in latency testing?

I wrote a simple test to compare the performance of Lock and synchronized.

This code allows you to change the number of threads (1 thread means there is no contention) and the number of contenders. Measured by coordinated omission and no omissions.

Use Lock or synchronised to run the test.

To record the results, I used the Histogram class. This class is created by Peter Lawrey. You can find this class in the utility class of Chronicle-Core.

Import org.junit.Test; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class LockVsSync {private static final boolean COORDINATED_OMISSION = Boolean.getBoolean ("coordinatedOmission"); / / Either run testing Lock or testing synchronized private static final boolean IS_LOCK = Boolean.getBoolean ("isLock"); private static final int NUM_THREADS = Integer.getInteger ("numThreads"); @ Test public void test () throws InterruptedException {Lock lock = new ReentrantLock () For (int t = 0; t

< NUM_THREADS; t++) { if (t == 0) { //Set the first thread as the master which will be measured //设置***个线程作为测量的线程 //The other threads are only to cause contention //其他线程只是引起竞争 Runner r = new Runner(lock, true); r.start(); } else { Runner r = new Runner(lock, false); r.start(); } } synchronized(this){ //Hold the main thread from completing wait(); } } private void testLock(Lock rlock) { rlock.lock(); try { for (int i = 0; i < 2; i++) { double x = 10 / 4.5 + i; } } finally { rlock.unlock(); } } private synchronized void testSync() { for (int i = 0; i < 2; i++) { double x = 10 / 4.5 + i; } } class Runner extends Thread { private Lock lock; private boolean master; public Runner(Lock lock, boolean master) { this.lock = lock; this.master = master; } @Override public void run() { Histogram histogram = null; if (master) histogram = new Histogram(); long rate = 1000;//expect 1 every microsecond long now =0; for (int i = -10000; i 0){ if(!COORDINATED_OMISSION) { now += rate; while(System.nanoTime() =0 && master){ histogram.sample(System.nanoTime() - now); } } if (master) { System.out.println(histogram.toMicrosFormat()); System.exit(0); } } } } 结果如下: 这是没有遗漏(co-ordinated omission)的结果: 采用微秒来衡量。 图形的顶部就是延迟的分布。 这是有竞争的测试,使用四个线程执行该程序。 这个测试是在8核的 MBP i7 上运行的。 每次测试迭代200,000,000次,并有10,000次预热。 根据吞吐率为每微妙迭代一次来调整遗漏。

As we expected, when there is no competition, the result is basically the same. JIT has optimized Lock and synchronized. When there is competition, using Lock is slightly faster when the percentage of occupancy is low, but the difference is really small. Therefore, even if there are many young GC (minor GC), they do not significantly reduce the efficiency of Lock. If they are all lightweight Lock, they are generally faster.

This is the result of adjustment to omission.

Of course, the delay will be higher if there are omissions.

Again, you can see that lock and synchronized have the same performance without competition-- which is not surprising.

Under competitive conditions, when the percentage is 99%, we see that synchronized performs 10x better than lock. After that, the performance of the two is basically the same.

I guess this is because the efficiency of GC recycling causes lock to be slower than synchronised, about every 3-1200 subtly GC recycling occurs. Especially after reaching 99%, the slowness is quite obvious. After that, the delay rate may be related to hardware and operating system (OS). But yes, this is only my personal inference, there is no more in-depth investigation.

The above is the example analysis of delayed Lock vs Synchronized in Java. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report