Java同步-Mutex.wait vs List.wait

Java同步-Mutex.wait vs List.wait,java,synchronization,Java,Synchronization,使用Java线程原语构造线程安全的有界队列时,这两种构造之间有什么区别 创建显式锁对象 使用列表作为锁并等待它 示例1 private final Object lock = new Object(); private ArrayList<String> list = new ArrayList<String>(); public String dequeue() { synchronized (lock) { while (list.size(

使用Java线程原语构造线程安全的有界队列时,这两种构造之间有什么区别

  • 创建显式锁对象
  • 使用列表作为锁并等待它
  • 示例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();
        }
    }
    
    private final Object lock=new Object();
    private ArrayList list=new ArrayList();
    公共字符串出列(){
    已同步(锁定){
    while(list.size()==0){
    lock.wait();
    }
    字符串值=列表。删除(0);
    lock.notifyAll();
    返回值;
    }
    }    
    公共void排队(字符串值){
    已同步(锁定){
    while(list.size()==maxSize){
    lock.wait();
    }
    列表。添加(值);
    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();
        }
    }
    
    private ArrayList list=new ArrayList();
    公共字符串出列(){
    已同步(列表){//锁定列表
    while(list.size()==0){
    list.wait();//在列表上等待
    }
    字符串值=列表。删除(0);
    list.notifyAll();
    返回值;
    }
    }
    公共void排队(字符串值){
    已同步(列表){//锁定列表
    while(list.size()==maxSize){
    list.wait();//在列表上等待
    }
    列表。添加(值);
    list.notifyAll();
    }
    }
    

  • 这是一个有界列表
  • 除排队和退队外,没有其他操作正在执行
  • 我可以使用阻塞队列,但这个问题更多是为了提高我有限的线程知识
  • 如果这个问题重复,请让我知道

  • 简单的回答是,没有,除了维护额外的锁对象所带来的额外内存开销之外,没有功能上的区别。然而,在做出最终决定之前,我会考虑一些语义相关的项目。 我是否需要对不仅仅是我的内部列表执行同步操作?

    假设您希望维护与
    ArrayList
    的并行数据结构,以便列表上的所有操作和该并行数据结构都需要同步。在这种情况下,最好使用外部锁,因为列表或结构上的锁可能会让将来在这个类上的开发工作感到困惑

    我会在队列类之外访问我的列表吗?

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


    我相信你可能会选择其中一个而不是另一个的原因还有很多,但这是我能想到的两个主要原因。

    不多,除了你还需要制作
    最终列表
    ,如果你需要同步访问列表之外的其他内容和访问列表,使用专用的
    lock
    会更清楚。第1点-理解,这肯定是一个主要区别