ReentrantReadWriteLock
在前面的文章中,我们深入探讨了 ReentrantLock,它是一个功能强大的独占锁。但在很多业务场景中,读操作的频率远远高于写操作。如果此时仍然使用 ReentrantLock,即使是多个读线程之间互不影响,它们也必须排队等待,这无疑大大降低了并发性能。
5 分钟阅读
2141 字
在前面的文章中,我们深入探讨了 ReentrantLock,它是一个功能强大的独占锁。但在很多业务场景中,读操作的频率远远高于写操作。如果此时仍然使用 ReentrantLock,即使是多个读线程之间互不影响,它们也必须排队等待,这无疑大大降低了并发性能。
在高并发编程领域,线程安全是一个绕不开的话题。Java 通过 synchronized 关键字为我们提供了一种简单易用的内置锁机制,用于保证共享数据在多线程环境下的原子性、可见性和有序性。然而,凡事有利必有弊,锁在带来数据安全的同时,也可能成为性能的瓶颈。
在 Java 高并发编程领域,线程安全是无法回避的核心命题。翻开《阿里巴巴 Java 开发手册》,在并发处理章节中有一条引人注目的强制性规范:
我们通常这样创建一个线程来执行任务:
public class ThreadPoolExecutorDemo {
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("主线程结束");
}
static class MyThread extends Thread{
@Override
public void run() {
System.out.println("this is MyThread");
}
}
}public class ThreadPoolExecutorDemo {
public static void main(String[] args) {
//1. 使用匿名内部类的写法
Thread t0 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("子线程t0");
}
});
t0.start();
//2. 使用lambda表达式的写法
Thread t1 = new Thread(()->{
System.out.println("这是子线程t1");
});
t1.start();
System.out.println("主线程结束");
}
}public class ThreadPoolExecutorDemo {
public static void main(String[] args) {
//把Callable对象传给FutureTask
FutureTask<String> futureTask = new FutureTask(new Callable() {
@Override
public Object call() throws Exception {
return "子线程futuretask";
}
});
Thread t3 = new Thread(futureTask);
t3.start();
//这里是个阻塞方法,会等待子线程返回result后,主线程才会继续执行
try {
String result = futureTask.get();
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("主线程结束");
}
}