Java21虚拟线程中为什么不能使用synchronizd关键字

501 阅读1分钟

平台线程与虚拟线程

平台线程是操作系统进行调度的,是java中传统的Thread
虚拟线程是jvm进行的调度的,虚拟线程实际上是挂载在平台线程上,当jvm检测到虚拟线程处于阻塞时,会将阻塞的虚拟线程从平台线程卸载,去运行其余的虚拟线程

synchronized与lock的区别

synchronized会阻塞平台线程,使得平台线程无法切换其余虚拟线程运行,导致效率无法达到预期
而lock只会阻塞虚拟线程,平台线程可以切换其余虚拟线程运行

实际效率对比

运行结果:
cost 4014为使用lock的结果
cost 12002为使用synchronized的结果

image.png

代码

	import java.util.concurrent.ExecutorService;
	import java.util.concurrent.Executors;
	import java.util.concurrent.locks.ReentrantLock;
	 
	public class Test {
	    public static void main(String[] args) {
	        testVirtualThread();
	    }
	 
	    private static void testVirtualThread() {
	        costTimeVirtualThread(Test::testLock);
	        costTimeVirtualThread(Test::testSynchronized);
	    }
	 
	    private static void costTimeVirtualThread(Runnable runnable) {
	        long start = System.currentTimeMillis();
	        try (ExecutorService executorService = Executors.newVirtualThreadPerTaskExecutor()) {
	            // 这个数字,根据自己电脑的核心数修改
	            for (int i = 0; i < 30; i++) {
	                executorService.submit(runnable);
	            }
	        }
	        System.out.printf("cost %s\n", System.currentTimeMillis() - start);
	    }
	 
	    private static void testSynchronized() {
	        Object test = new Object();
	        synchronized (test) {
	            sleep();
	        }
	    }
	 
	    private static void sleep() {
	        try {
	            Thread.sleep(4000);
	        } catch (InterruptedException e) {
	            throw new RuntimeException(e);
	        }
	    }
	 
	    private static void testLock() {
	        ReentrantLock lock = new ReentrantLock();
	        lock.lock();
	        sleep();
	        lock.unlock();
	    }
	}