多线程新手——如何在java中使用wait()和notify()?

发布于 2024-09-10 21:06:30 字数 817 浏览 7 评论 0原文

我正在尝试编写一个包含 2 个类的程序,一个控制器和一个执行大量计算的类。控制器创建另一个类的几个实例,然后告诉它们全部开始计算(并行)。它们各自在完成后返回,控制器恢复,然后,一段时间后,控制器向它们传递新数据,并让它们再次运行计算。
理想情况下,我可以使用参数调用 start() ,但这是不可能的,因此控制器调用计算器中的一个方法,将数据存储在全局中,然后启动计算线程并返回,直到我尝试再次启动线程,它告诉我线程已死。因此,我试图使运行成为一个无限循环,只等待直到收到通知,运行计算,将结果存储在全局中,以便控制器稍后可以检索它们,然后恢复等待。所以像这样:

//in controller:
Calculator calc=new Calculator();
calc.runCalculations(data);
while(calc.isCalculating()){
    //do nothing
}
System.out.println("results: "+calc.getAnswer());
calc.runCalculations(data2);

//in calculator:
public runCalculations(Data data){
    globalData=data;
    this.notify();
}
public void run(){
    while(true){
        synchronized(this){
            wait();
        }
        calculating=true;
        globalData=calculate(globalData);
        calculating=false;
    }
}

I'm trying to write a program with 2 classes, a controller and a class that does a lot of computation. The controller creates a couple instances of the other class, then tells them all to start their calculations (in parallel). They each return when they are finished, and the controller resumes, and then, some time later, the controller passes them new data, and has them run the calculation again.
Ideally, I would be able to call start() with parameters, but that isn't possible, so the controller calls a method in the calculator that stores the data in a global, and then starts the calculation thread and returns, which works until I try to start the thread again, and it tells me the thread is dead. So I'm trying to make the run an infinite loop that just waits until it is notified, runs the calculations, stores the results in a global so the controller can retrieve them later, then resumes waiting. So something like:

//in controller:
Calculator calc=new Calculator();
calc.runCalculations(data);
while(calc.isCalculating()){
    //do nothing
}
System.out.println("results: "+calc.getAnswer());
calc.runCalculations(data2);

//in calculator:
public runCalculations(Data data){
    globalData=data;
    this.notify();
}
public void run(){
    while(true){
        synchronized(this){
            wait();
        }
        calculating=true;
        globalData=calculate(globalData);
        calculating=false;
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

帥小哥 2024-09-17 21:06:30

在调用 notify() 之前,您需要获取 this 上的监视器。
另外,当您调用 wait() 时,您应该在一个循环中执行此操作,以检查条件以确保您没有遇到虚假唤醒。

public runCalculations(Data data){
    globalData=data;
    synchronized(this) {
        calculating=true;
        this.notify();
    }
}
public void run(){
    while(true){
        synchronized(this){
            calculating=false;
            while(!calculating) {
                wait();
            }
        }
        globalData=calculate(globalData);
    }
}

一般来说,大多数人会建议不要使用等待/通知,而是建议您使用 Executor 或至少使用 BlockingQueue。但这两者都需要你重新设计你目前的想法。

You need to obtain the monitor on this before you call notify().
Also, when you call wait() you should do so in a loop that checks a condition to be certain that you did not experience a spurious wakeup.

public runCalculations(Data data){
    globalData=data;
    synchronized(this) {
        calculating=true;
        this.notify();
    }
}
public void run(){
    while(true){
        synchronized(this){
            calculating=false;
            while(!calculating) {
                wait();
            }
        }
        globalData=calculate(globalData);
    }
}

In general, most people would advise against using wait/notify and instead recommend you use an Executor or at the very least a BlockingQueue. But both of those would require you to redesign what you are currently thinking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文