【问题标题】:Java Synchronization - Mutex.wait vs List.waitJava 同步 - Mutex.wait 与 List.wait
【发布时间】:2013-06-06 18:58:33
【问题描述】:

在使用 Java Threading Primitives 构造线程安全的有界队列时 - 这两种构造之间有什么区别

  1. 创建显式锁定对象。
  2. 使用列表作为锁并等待它。

1 示例

private final Object lock = new Object();
private ArrayList<String> list = new ArrayList<String>();

public String dequeue() {
    synchronized (lock) {
        while (list.size() == 0) {
            lock.wait();
        }

        String value = list.remove(0);
        lock.notifyAll();
        return value;
    }
}    

public void enqueue(String value) {
    synchronized (lock) {
        while (list.size() == maxSize) {
            lock.wait();
        }

        list.add(value);
        lock.notifyAll();
    }
}

2 示例

private ArrayList<String> list = new ArrayList<String>();

public String dequeue() {
    synchronized (list) {  // lock on list
        while (list.size() == 0) {
           list.wait();     // wait on list
        }

        String value = list.remove(0);
        list.notifyAll();  
        return value;
    }
}


public void enqueue(String value) {
    synchronized (list) {  // lock on list
        while (list.size() == maxSize) {
           list.wait();   // wait on list
        }

        list.add(value);
        list.notifyAll();
    }
}

注意

  1. 这是一个有界列表
  2. 除了入队和出队外,没有执行其他操作。
  3. 我可以使用阻塞队列,但这个问题更多是为了提高我有限的线程知识。
  4. 如果此问题重复出现,请告诉我。

【问题讨论】:

  • 不多,除非您还需要创建final list,并且如果您需要同步对列表之外的其他内容的访问对列表的访问,使用专用的lock 会更清楚。

标签: java synchronization


【解决方案1】:

简短的回答是,不,除了维护那个额外的锁对象的额外内存开销之外,没有任何功能差异。但是,在做出最终决定之前,我会考虑一些与语义相关的项目。

我是否需要对我的内部列表以外的其他对象执行同步操作?

假设您想为您的ArrayList 维护一个并行数据结构,以便列表上的所有操作和该并行数据结构都需要同步。在这种情况下,最好使用外部锁,因为锁定在列表或结构上可能会混淆该类的未来开发工作。

我会在队列类之外授予对列表的访问权吗?

假设你想为你的列表提供一个访问器方法,或者让它对你的 Queue 类的扩展可见。如果您使用的是外部锁对象,则检索对列表的引用的类将永远无法在该列表上执行线程安全操作。在这种情况下,最好在列表上同步,并在 API 中明确说明对列表的外部访问/修改也必须在该列表上同步。

我确信您可能会选择其中一个而不是另一个,但这是我能想到的两大原因。

【讨论】:

  • 第 1 点 - 明白,这绝对是一个主要区别
猜你喜欢
  • 1970-01-01
  • 2010-10-08
  • 1970-01-01
  • 1970-01-01
  • 2012-02-03
  • 2013-03-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
相关资源
最近更新 更多