Java用另一个对象监视一个对象

标签 java multithreading concurrency synchronization monitoring

我想说,我试图在这个网站上找到一些答案,但我无法管理,这也是我的第一个问题,所以如果我把它写掉格式等,我很抱歉......

我正在尝试学习java,现在正在尝试理解线程部分。到目前为止,我了解了一些基础知识,我想尝试一下:中尉类别与士兵类别共享监视器锁,但我在某个地方失败了。

编辑:我希望中尉等到士兵说出第一句话,然后他发出命令。但是,当士兵尝试释放锁时,由于通知方法,我收到监视器错误。 “线程“Thread-1”java.lang.IllegalMonitorStateException 中出现异常。”

P.S:我知道有更简单的方法,但我正在尝试利用 wait¬ify。

public class Lieutenant {
private boolean waitForCommand = true;
public void setWaitForCommand(boolean waitForCommand) {
    this.waitForCommand = waitForCommand;
}
public synchronized void giveOrder() {
    while (waitForCommand) {
        try {
            wait();
        } catch (InterruptedException e) {
            e.getStackTrace();
        }
        System.out.println("I said run soldier! RUN!");
    }}}




public class Soldier {
private final Lieutenant lieutenant;

public Soldier(Lieutenant lieutenant) {
    this.lieutenant = lieutenant;
}
public void getOrder() {
    synchronized (this.lieutenant) {
        System.out.println("Sir! Yes, sir!");
        lieutenant.setWaitForCommand(false);
        notifyAll();
    }}}


class Main {

public static void main(String[] args) {

    Lieutenant lieutenant = new Lieutenant();
    Soldier soldier = new Soldier(lieutenant);
    new Thread(new Runnable() {
        @Override
        public void run() {
            lieutenant.giveOrder();
        }}).start();

    new Thread(new Runnable() {
        @Override
        public void run() {
            soldier.getOrder();
        }}).start();
}}

最佳答案

这里最直接的问题是这个方法:

synchronized (this.lieutenant) {
        System.out.println("Sir! Yes, sir!");
        lieutenant.setWaitForCommand(false);
        notifyAll();
    }}

同步块(synchronized block)正在锁定 this.lieutenant,但您尝试在 this 上调用 notifyAll(),而您却没有这样做没有保持锁定状态。

如果进行此更改

synchronized (this.lieutenant) {
        System.out.println("Sir! Yes, sir!");
        lieutenant.setWaitForCommand(false);
        this.lieutenant.notifyAll();
    }}

它应该工作得更好。但正如评论中提到的,您不能保证 giveOrder 将在 getOrder 之前调用。

关于Java用另一个对象监视一个对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58866753/

相关文章:

java - 如何找到特定字符串在图像上的位置?

scala - 为什么Scala有利于并发?

java - 通过参数同步 Java 方法

java方法重载为不同的方法共享相同的内存或不同的内存

Linux ext3 readdir 和并发更新

Java 将实时视频输入流发送到 Red5 媒体服务器

Java 和 JSR-223 在 Coldfusion 服务器上运行 Python(或 Ruby)代码

xml - Java XML 文件比较

c# - 在哪里放置栅栏/内存屏障以保证新的读取/提交的写入?

c# - 并发词典的正确用法