繁体   English   中英

了解多线程

[英]Understanding multi-threading

关于并发运行的线程以及它们对对象的锁定,我只是有一个问题。 据我所知,调用wait()方法的线程将进入等待列表,并允许来自阻塞列表的另一个线程接管锁定和对象(在同步代码中)。 如果现在对该对象具有锁定的此线程调用notify()方法,则它会唤醒调用wait()的线程,并将其移动到阻止列表。

调用notify()方法的线程会发生什么。 它是否仍然锁定对象或现在是否在等待列表?

问候

只有一个线程可以保持对象的锁定。 当线程持有对您调用这些方法的对象的锁时,必须调用wait()notify()方法; 如果他们不这样做(例如,因为你没有在对象上同步),你将得到一个IllegalMonitorStateException

当你调用wait() ,线程放弃锁定并进入等待列表(停止执行)。 wait()返回时,线程将再次获得锁定。 但是,调用notify()的线程仍然保持锁定,因此在通知线程退出synchronized块或方法之前,等待线程不会恢复,以便释放对象的锁定。

通过调用notify() ,线程不会放弃对象的锁定。

一系列可能的事件将是:

  • 线程1进入synchronized块,获得对象的锁定
  • 线程1调用对象上的wait() ,放弃锁定,停止执行
  • 线程2进入synchronized块,获得对象的锁定
  • 线程2调用对象上的notify() ,但仍保持锁定
  • 线程1被唤醒并尝试获取锁定,但它不能,因为线程2仍然拥有它(因此线程1必须等待锁定)
  • 线程2退出synchronized块并释放锁定
  • 线程1现在可以获取锁并从wait()返回

通知线程仍然拥有锁。 请参阅文档部分17.14(页面底部):

仅当当前线程已锁定对象的锁定时,才应为对象调用notify方法。 如果对象的等待集不为空,则从等待集中删除一些任意选择的线程并重新启用以进行线程调度。 (当然,在当前线程放弃对象的锁定之前,该线程将无法继续。)

不,它将通过保留同步块或从同步方法返回来释放锁定。 在再次调用wait()之前,它不会返回等待列表。

暂无
暂无

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

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