A simple performance test for synchronized and Lock locks

Posted by medaswho on Mon, 23 Sep 2019 13:13:28 +0200

For these two kinds of locks, the performance of synchronized before JDK1.6 is far inferior to that of Lock, because synchronized needs to call the functions of the operating system and operate the kernel to complete, which is time-consuming. After JDK1.6, Oracle has optimized synchronized a lot, and synchronized is also programmed by CAS from the heavyweight locks. With the JVM level lock, the performance has been greatly improved. JDK 1.8 is widely used now. Out of curiosity, I have simply tested the performance of synchronized and Lock under JDK 1.8.

Under single thread, using synchronized and Lock to perform 100 0-1 million superposition operations, respectively, the test code is as follows

public static void main(String[] args) throws InterruptedException {
		long start = System.currentTimeMillis();
		for (int i = 0; i < 100; i++) {
			function1();
		}
		System.out.println("Single thread, synchronized time consuming:" + (System.currentTimeMillis() - start));

		Thread.sleep(1000);

		Lock lock = new ReentrantLock();
		long start2 = System.currentTimeMillis();
		for (int i = 0; i < 100; i++) {
			function2(lock);
		}
		System.out.println("Single thread, Lock time consuming:" + (System.currentTimeMillis() - start2));
	}

	/**
	 * Using synchronized to stack 1-1 million
	 */
	public static void function1() {
		synchronized ("demo") {
			int sum = 0;
			for (int i = 0; i < 1000000; i++) {
				sum += i;
			}
		}
	}
	/**
	 * Use Lock for 1-1 million overlays
	 */
	public static void function2(Lock lock) {
		lock.lock();
		int sum = 0;
		for (int i = 0; i < 1000000; i++) {
			sum += i;
		}
		lock.unlock();
	}

Results (3 executions):

Single thread, synchronized time-consuming:5
 Single thread, Lock time-consuming:8

Single thread, synchronized time-consuming: 6
 Single thread, Lock time-consuming:9

Single thread, synchronized time-consuming:5
 Single thread, Lock time-consuming:9

Under 10 threads, synchronized and lock are used to perform 100 times of 0-1 million superposition operations. The test code is as follows:

/**
 * synchronized Runable class
 */
class SyncTest implements Runnable {

	@Override
	public synchronized void run() {
		for (int i = 0; i < 100; i++) {
			function();
		}
	}

	public void function() {
		int sum = 0;
		for (int i = 0; i < 1000000; i++) {
			sum += i;
		}
	}
}
/**
 * Lock Runable class
 */
class LockTest implements Runnable{

	private Lock lock;

	public LockTest(Lock lock) {
		this.lock = lock;
	}

	@Override
	public void run() {
		lock.lock();
		for (int i = 0; i < 100; i++) {
			function();
		}
		lock.unlock();
	}

	public void function() {
		int sum = 0;
		for (int i = 0; i < 1000000; i++) {
			sum += i;
		}
	}
}

public static void main(String[] args) throws InterruptedException {
		long start = System.currentTimeMillis();
		List<Thread> threads1 = new ArrayList<>();
		for (int i = 0; i < 10; i++) {
			Thread thread = new Thread(new SyncTest());
			threads1.add(thread);
			thread.start();
		}
		for (Thread thread : threads1) {
			thread.join();
		}
		System.out.println("10 Thread, synchronized Time consuming:"+(System.currentTimeMillis()-start));

		Thread.sleep(1000);

		Lock lock = new ReentrantLock();
		List<Thread> threads = new ArrayList<>();
		long start2 = System.currentTimeMillis();
		for (int i = 0; i < 10; i++) {
			Thread thread = new Thread(new LockTest(lock));
			threads.add(thread);
			thread.start();
		}
		for (Thread thread : threads) {
			thread.join();
		}
		System.out.println("10 Thread, lock Time consuming:"+(System.currentTimeMillis()-start2));
	}

Results (3 executions):

10 threads, synchronized time-consuming: 12
 10 threads, lock time-consuming: 15

Ten threads, synchronized: 18
 10 threads, lock time-consuming: 19

Ten threads, synchronized: 16
 10 threads, lock time-consuming: 27

Finally, with the same code logic as above, I set the number of threads to 1000, and because the number of threads opened is too large to affect the data results, I separated the Lock and synchronized tests and got the following results (three executions):

1000 threads, synchronized time: 87
 1000 threads, synchronized time-consuming: 82
 1000 threads, synchronized time-consuming: 79

1000 threads, lock time-consuming: 84
 1000 threads, lock time-consuming: 79
 1000 threads, lock time-consuming: 85

As you can see, synchronized seems to perform a little better than Lock when threads compete less, but when threads compete fiercely, they are almost the same.

Topics: JDK Oracle jvm less