简体   繁体   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, as far as I understand both somewhat achieve the same. 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 ,据我了解,两者在某种程度上都达到了相同的效果。

In other words: This换句话说:这

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

vs This与这个

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

Is the difference in that the first one locks the whole object thus no other thread gets access to that shared region and in the second one we get more flexibility in what we want to lock down?区别在于第一个锁定整个 object 因此没有其他线程可以访问该共享区域,而在第二个中,我们可以更灵活地锁定我们想要锁定的内容?

Second question since putting this in a comment is hard (editing main post for it):第二个问题,因为将其放在评论中很难(为其编辑主要帖子):

I have a problem Im trying to resolve and figuring the best way to architect the class, the problem is as follows there's an airport with a queue (shared region) and three threads (pilot,hostess and passenger), the hostess is basically the check in from the airport.我有一个问题我试图解决并找出构建 class 的最佳方法,问题如下有一个机场有一个队列(共享区域)和三个线程(飞行员、女主人和乘客),女主人基本上是检查从机场进来。

The passenger first enters queue and waits for the operation checkDocuments from the hostess (so it gets in a blocking/waiting state) then it presents the plane ticket and waits for the operation waitForNextPassenger of the hostess to procceed inside the plane.乘客首先进入队列等待女主人的操作 checkDocuments(因此进入阻塞/等待状态),然后出示机票并等待女主人的操作 waitForNextPassenger 进入飞机内。 The hostess on the other hand wakes up by the operation waitInQueue of the passenger (when it first enters the queue), checks the passenger and then gets in another wait state that waits for the passengers documents and then checks in the passenger.另一方面,女主人被乘客的操作 waitInQueue 唤醒(当它第一次进入队列时),检查乘客然后进入另一个等待 state 等待乘客文件然后检查乘客。

Given this I have defined these blocking variables: waitInQueue checkDocuments showingDocuments waitForNextPassenger鉴于此,我已经定义了这些阻塞变量: waitInQueue checkDocuments shownDocuments waitForNextPassenger

Given what you said in the comment, I suppose a good approach would be to make each of these an object and for example in the thread passenger lifecycle it would call the method WaitInQueue that would wait for the object checkDocuments (checkDocuments.wait) and the hostess would for example checkDocuments.notify鉴于您在评论中所说的,我想一个好的方法是将这些中的每一个都设为 object,例如在线程乘客生命周期中,它将调用等待 object checkDocuments (checkDocuments.wait) 和女主人会例如 checkDocuments.notify

Is this a correct approach?这是一个正确的方法吗?

A synchronized method:同步方法:

public void synchronized f() {...}

is identical to:等同于:

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

which is different from:这不同于:

private Object obj=new Object()

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

The synchronized method uses this , which means any other synchronized method working on the same object will wait until the current synchronized method returns.同步方法使用this ,这意味着在同一 object 上工作的任何其他同步方法将等待当前同步方法返回。 When you use a separate object with a synchronized block, the synchronized block will wait until the current synchronized block using the same object exits.当您将单独的 object 与同步块一起使用时,同步块将等到使用相同 object 的当前同步块退出。 So with the second approach, you can do:因此,使用第二种方法,您可以执行以下操作:

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

That is, you can control the mutual exclusion in a more granular way.也就是说,您可以以更精细的方式控制互斥。

The second approach also allows you to lock multiple objects.第二种方法还允许您锁定多个对象。

You have to be careful about wait / notify when you're using the second approach.当您使用第二种方法时,您必须小心wait / notify You can call obj.wait() if you are holding the lock for obj , meaning you are in a synchronized block synchronized(obj) .如果您持有obj的锁,则可以调用obj.wait() ,这意味着您处于同步块synchronized(obj)中。 When wait is called, the synchronized block will relinquish the lock on that object.当调用wait时,同步块将放弃对 object 的锁定。 Then, another thread can use obj.notify() to send notifications to waiting threads.然后,另一个线程可以使用obj.notify()向等待线程发送通知。

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

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