Java: 在不同线程之间共享锁的最佳方式
Java: best way to share Lock between different threads
是否建议将外部锁实现为 class 的属性,将在不同线程之间共享?
例如我想要这样的实现:
public class Order {
private final LinkedList<Food> order;
private final int orderNum;
private static int idGen;
private final Lock lock;
private final Condition isDone;
public Order() {
// TODO Auto-generated constructor stub
this.order = new LinkedList<>();
this.orderNum = ++idGen;
this.lock = new ReentrantLock();
this.isDone = lock.newCondition();
}
public static Order createOrder(){
return new Order();
}
public void add(Food food){
synchronized (food) {
order.add(food);
}
}
public LinkedList<Food> getOrder() {
return order;
}
public int getOrderNum() {
return orderNum;
}
public synchronized boolean isEmpty(){
return this.order.isEmpty();
}
}
然后假设我有两个线程,分别称为 Customer 和 Cook。 Cook 将尝试清空共享 Order 对象的 LinkedList,而 Customer 将不断检查他的订单是否已完成,例如变空。我的目的是在共享 Order 对象中使用锁。当库克完成他的工作时,他会调用 order.getIsDone().signal() 来唤醒等待相同条件的客户线程,例如
while(!order.isEmpty()) order.getIsDone().await();
我想到这个想法的原因是我想在绑定到某个 Order 对象时在两个线程之间共享同一个锁。但是,由于 Order 对象在不同线程之间共享,因此可能存在并发问题。所以,我不确定这种实施是一个明智的选择。
我能想到的替代方案是用 yield() 替换 order.getIsDone().await(),但它会导致一些性能损失,同时它更简单。
锁的整个想法是它们在线程之间共享!
所以是的,锁定对象的一个字段,并使用条件检查订单是否完成。
请记住,您需要在锁定后始终解锁锁,因此模式是
lock.lock();
try {
...
} finally {
lock.unlock();
}
你在循环中等待你的条件(但你已经知道了)。
如果您已经在使用锁,则不需要在其他两个方法(isEmpty、add)上同步,因为锁速度更快,所以请改用它。
是否建议将外部锁实现为 class 的属性,将在不同线程之间共享?
例如我想要这样的实现:
public class Order {
private final LinkedList<Food> order;
private final int orderNum;
private static int idGen;
private final Lock lock;
private final Condition isDone;
public Order() {
// TODO Auto-generated constructor stub
this.order = new LinkedList<>();
this.orderNum = ++idGen;
this.lock = new ReentrantLock();
this.isDone = lock.newCondition();
}
public static Order createOrder(){
return new Order();
}
public void add(Food food){
synchronized (food) {
order.add(food);
}
}
public LinkedList<Food> getOrder() {
return order;
}
public int getOrderNum() {
return orderNum;
}
public synchronized boolean isEmpty(){
return this.order.isEmpty();
}
}
然后假设我有两个线程,分别称为 Customer 和 Cook。 Cook 将尝试清空共享 Order 对象的 LinkedList,而 Customer 将不断检查他的订单是否已完成,例如变空。我的目的是在共享 Order 对象中使用锁。当库克完成他的工作时,他会调用 order.getIsDone().signal() 来唤醒等待相同条件的客户线程,例如 while(!order.isEmpty()) order.getIsDone().await();
我想到这个想法的原因是我想在绑定到某个 Order 对象时在两个线程之间共享同一个锁。但是,由于 Order 对象在不同线程之间共享,因此可能存在并发问题。所以,我不确定这种实施是一个明智的选择。
我能想到的替代方案是用 yield() 替换 order.getIsDone().await(),但它会导致一些性能损失,同时它更简单。
锁的整个想法是它们在线程之间共享!
所以是的,锁定对象的一个字段,并使用条件检查订单是否完成。
请记住,您需要在锁定后始终解锁锁,因此模式是
lock.lock();
try {
...
} finally {
lock.unlock();
}
你在循环中等待你的条件(但你已经知道了)。
如果您已经在使用锁,则不需要在其他两个方法(isEmpty、add)上同步,因为锁速度更快,所以请改用它。