Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/ant/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
等待和通知的Java线程同步对象_Java_Multithreading_Synchronization - Fatal编程技术网

等待和通知的Java线程同步对象

等待和通知的Java线程同步对象,java,multithreading,synchronization,Java,Multithreading,Synchronization,当我们在线程环境中使用wait和notify时。我有一个类来处理数据作为后台进程。当没有数据要处理时,它应该调用wait synchronized(some_object){ wait(); } 在另一个类中,我再次添加数据。我需要调用notify()方法 synchronized(some_object){ runnabale_object.notify(); } 为什么我应该在这两个不同的类中对同步块使用相同的对象。正如我读到的,同步是用来 “Synchronized”关键字

当我们在线程环境中使用wait和notify时。我有一个类来处理数据作为后台进程。当没有数据要处理时,它应该调用wait

synchronized(some_object){
   wait();
}
在另一个类中,我再次添加数据。我需要调用
notify()
方法

synchronized(some_object){
   runnabale_object.notify();
}
为什么我应该在这两个不同的类中对同步块使用相同的对象。正如我读到的,同步是用来

“Synchronized”关键字可防止对数据块的并发访问 代码或对象由多个线程执行

但这两个街区是不同的。但是当我们使用多线程时,我可以理解这个问题。当一个线程阻塞时,另一个线程可以在同一个线程调用notify之前调用notify

我的问题

  • 我们可以为单线程环境使用不同的锁对象吗
  • 当我们在不同的类中有wait和notify时,使用同一个锁对象的最佳方法是什么
我们可以为单线程环境使用不同的锁对象(同步的(对象))吗

在单线程环境中,不需要锁。你可以使用你想要的任何东西,也可以什么都不用

在单线程环境中,可以保证没有线程正在等待(),因此notify()不会执行任何操作

当我们在不同的类中有wait和notify时,使用同一个锁对象的最佳方法是什么

通知()时,必须执行状态更改。当您在循环中等待()时,您需要检查大量的状态更改。如果你不这样做,你会有两个问题

  • notify()已丢失
  • 等待的人突然醒过来
当没有数据要处理时,它应该调用wait

synchronized(some_object){
   wait();
}
不是在什么时候,而是在什么时候

Wait和notify是低级的基本操作,旨在以非常特定的方式使用

在消费者线程中:

synchronized(lock) {
    while (thereIsNothingToProcess()) {
        lock.wait();
    }
    processSomething();
}
synchronized(lock) {
    makeSomethingAvailableToProcess();
    lock.notifyAll();    //or lock.notify() if you think you can get away with it.
}
在生产者线程中:

synchronized(lock) {
    while (thereIsNothingToProcess()) {
        lock.wait();
    }
    processSomething();
}
synchronized(lock) {
    makeSomethingAvailableToProcess();
    lock.notifyAll();    //or lock.notify() if you think you can get away with it.
}
如果您遵循此确切模式,则:

  • 当多个消费者竞相处理同一件物品时,您不会遇到麻烦
  • 您不会因为虚假唤醒而陷入麻烦,并且
  • 您不会因为丢失通知问题而遇到麻烦

    • 我有同样的问题,所以我查了一下。在同一个对象中可以使用两个同步块的原因是“wait()”实际上会释放监视器,以便其他线程可以获得同一对象的守护者。

      您必须在锁定对象上调用
      wait
      notify
      (在您的情况下,
      some\u object.wait()
      some\u object.notify())
      )!您的代码实际上无法正常工作,当前线程必须拥有此对象的监视器。(我的重点)。因此,如果要使用
      wait
      /
      notify
      ,那么等待/通知
      线程必须拥有它正在操作的
      对象的监视器。这也回答了您的问题,您必须使用相同的对象进行
      同步
      等待
      /
      通知
      。在我提到的情况下,当没有数据时,使用单线程处理数据。在新数据到来之前,我必须保持这个过程。所以我的等待和通知方法是错误的?对不起,我弄糊涂了。这里的单线程环境意味着我要创建一个单线程。因此,主线程可以正确地通知已创建的线程。显然,它是多线程的。rt?@Exbury您需要做的更改是wait()循环应该检查您是否真的有更多数据。我假设只有在添加数据后才会调用notify()。任何公共数据结构也应在同步块内更新/读取。顺便说一句,单线程写入和单线程读取仍然是一个多线程环境。