ReentrantLock适用场景
- 需要更灵活的锁控制场景:例如在复杂的同步控制逻辑中,需要实现锁的可中断获取、锁的公平性等功能。比如一个多线程任务调度系统,部分任务可能因为优先级高,希望在等待锁时可以中断等待去执行更紧急的任务。
import java.util.concurrent.locks.ReentrantLock;
public class TaskScheduler {
private static final ReentrantLock lock = new ReentrantLock();
public static void highPriorityTask() {
boolean gotLock = false;
try {
// 可中断地获取锁
gotLock = lock.tryLock();
if (gotLock) {
// 执行高优先级任务
System.out.println("执行高优先级任务");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.println("高优先级任务获取锁中断");
} finally {
if (gotLock) {
lock.unlock();
}
}
}
}
- 需要精确控制锁的粒度场景:在一些数据结构实现中,可能需要对不同部分进行更细粒度的锁控制。以实现一个支持并发操作的链表为例,可能需要对链表头、链表尾分别加锁。
import java.util.concurrent.locks.ReentrantLock;
public class ConcurrentLinkedList {
private Node head;
private Node tail;
private final ReentrantLock headLock = new ReentrantLock();
private final ReentrantLock tailLock = new ReentrantLock();
public void addToHead(Object value) {
headLock.lock();
try {
Node newNode = new Node(value);
newNode.next = head;
head = newNode;
if (tail == null) {
tail = head;
}
} finally {
headLock.unlock();
}
}
public void addToTail(Object value) {
tailLock.lock();
try {
Node newNode = new Node(value);
if (tail == null) {
head = tail = newNode;
} else {
tail.next = newNode;
tail = newNode;
}
} finally {
tailLock.unlock();
}
}
private static class Node {
Object value;
Node next;
Node(Object value) {
this.value = value;
}
}
}
Synchronized适用场景
- 简单同步场景:当同步代码块或方法逻辑较为简单,对锁的功能需求不复杂时,使用
synchronized
非常方便。例如在一个简单的计数器类中。
public class SimpleCounter {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
}
- 基于对象或类的同步场景:当需要基于对象实例或者类进行同步时,
synchronized
能自然地满足需求。例如一个单例模式的实现,确保只有一个实例被创建。
public class Singleton {
private static Singleton instance;
private Singleton() {}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}