繁体   English   中英

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

[英]Java Thread Synchronized object for wait and notify

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

synchronized(some_object){
   wait();
}

在另一堂课中,我再次添加数据。 我需要调用notify()方法。

synchronized(some_object){
   runnabale_object.notify();
}

为什么我应该在这两个不同的类中为同步块使用相同的对象。 当我阅读同步用于

“同步”关键字可防止多个线程同时访问代码块或对象。

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

我的问题

  • 我们可以在单线程环境中使用不同的锁对象(同步(对象))吗?
  • 当我们在不同的类中等待和通知时使用相同锁对象的最佳方式?

我们可以在单线程环境中使用不同的锁对象(同步(对象))吗?

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

在单线程环境中,您可以保证没有线程在等待(),因此通知()不会做任何事情。

当我们在不同的类中等待和通知时使用相同锁对象的最佳方式?

当您通知()时,您必须执行状态更改。 当您在循环中 wait() 时,您会检查该状态更改。 如果你不这样做,你可能会遇到两个问题。

  • 通知()丢失
  • 等待()虚假唤醒,即没有通知。

当没有要处理的数据时,它应该调用等待。

不是 when ,而是while

等待和通知是低级原始操作,旨在以非常特定的方式使用。

在消费者线程中:

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()'实际上会释放监视器,以便其他线程可以获得同一个对象的守护者。

暂无
暂无

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

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