繁体   English   中英

两种同步方式的区别

[英]Difference between two synchronization methods

I have a doubt that is somewhat confusing me in java thread synchronization, if I have a shared memory zone, what is the difference between using wait/notify/notifyAll in the synchronized methods and declaring an Object (Object myObj) and using myObj.wait ,据我了解,两者在某种程度上都达到了相同的效果。

换句话说:这

public class ThreadSignal{
    protected boolean isDataAvailable = false;
    public void synchronized waitUntilComplete(){
       if(isDataAvailable == false){
           wait();
       }
    }
    public void synchronized complete(){
       isDataAvailable = true;
       notify();
    }
}

与这个

private Object notEmpty = new Object();
private Object notFull = new Object();
public synchronized E take() {
        //some code
            notEmpty.wait()
        //some code
        notFull.notifyAll();
}

区别在于第一个锁定整个 object 因此没有其他线程可以访问该共享区域,而在第二个中,我们可以更灵活地锁定我们想要锁定的内容?

第二个问题,因为将其放在评论中很难(为其编辑主要帖子):

我有一个问题我试图解决并找出构建 class 的最佳方法,问题如下有一个机场有一个队列(共享区域)和三个线程(飞行员、女主人和乘客),女主人基本上是检查从机场进来。

乘客首先进入队列等待女主人的操作 checkDocuments(因此进入阻塞/等待状态),然后出示机票并等待女主人的操作 waitForNextPassenger 进入飞机内。 另一方面,女主人被乘客的操作 waitInQueue 唤醒(当它第一次进入队列时),检查乘客然后进入另一个等待 state 等待乘客文件然后检查乘客。

鉴于此,我已经定义了这些阻塞变量: waitInQueue checkDocuments shownDocuments waitForNextPassenger

鉴于您在评论中所说的,我想一个好的方法是将这些中的每一个都设为 object,例如在线程乘客生命周期中,它将调用等待 object checkDocuments (checkDocuments.wait) 和女主人会例如 checkDocuments.notify

这是一个正确的方法吗?

同步方法:

public void synchronized f() {...}

等同于:

public void f() {
  synchronized(this) {
  ...
  }
}

这不同于:

private Object obj=new Object()

public void f() {
  synchronized(obj) {
    ...
   }
}

同步方法使用this ,这意味着在同一 object 上工作的任何其他同步方法将等待当前同步方法返回。 当您将单独的 object 与同步块一起使用时,同步块将等到使用相同 object 的当前同步块退出。 因此,使用第二种方法,您可以执行以下操作:

public void f() {
   synchronized(obj) {
     ...
   }
   // Do stuff
   synchronized(obj) {
    ...
   }
}

也就是说,您可以以更精细的方式控制互斥。

第二种方法还允许您锁定多个对象。

当您使用第二种方法时,您必须小心wait / notify 如果您持有obj的锁,则可以调用obj.wait() ,这意味着您处于同步块synchronized(obj)中。 当调用wait时,同步块将放弃对 object 的锁定。 然后,另一个线程可以使用obj.notify()向等待线程发送通知。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM