gpt4 book ai didi

java - 如何进行线程交互?

转载 作者:行者123 更新时间:2023-11-30 10:43:30 24 4
gpt4 key购买 nike

我想使用多线程(低级线程),但我遇到了问题。问题是,因为至少 wait 方法将被一个线程调用,而 notifyAll 将被另一个线程调用".

我的代码如下:

public class Reader extends Thread {

Calculator c;

public Reader(Calculator cal) {
c=cal;
}

public void run (){
synchronized(c) {
try {
System.out.println("Waiting for calculation");
c.wait();
} catch (InterruptedException ex) {}
System.out.println("Total is:" +c.total);
}
}

public static void main (String[] a) {

Calculator calculator=new Calculator();

new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
}
}

class Calculator implements Runnable {

int total;

public void run() {
synchronized(this) {
for(int i=0;i<100;i++) {
total=total+i;
}
notifyAll();
}
}
}

我在这里得到的输出是连续 5 次等待计算,所以我永远不会达到“总计就是总计”的说法。

我正在尝试找出解决问题的方法,但仍未找到解决方案。如果有人知道该怎么做,我将不胜感激。

提前致谢

最佳答案

您实际上并没有执行可运行的计算器,您拥有的代码不会计算总数或通知任何内容。使用计算器启动一个新线程:

new Thread(calculator).start();

在您初始化计算器局部变量的行之后。这将使计算器在主线程启动读者时开始工作。

仍然有可能计算器可能会在读者开始等待之前完成,而读者最终将永远等待永远不会到来的通知。创建一个条件变量,在这种情况下向计算器添加一个 boolean 标志,您将其初始化为 false 并在完成计算后设置为 true(通过 notifyAll,在离开同步块(synchronized block)之前)。让读者循环等待:

synchronized(c) {
try {
System.out.println("Waiting for calculation");
while (!c.finished) {
c.wait();
}
} catch (InterruptedException ex) {}
System.out.println("Total is:" +c.total);
}

这样,如果计算器在读者开始之前完成,读者将从条件变量中得知计算器已完成,他们不会等待。

总是在循环中调用 wait 方法是一个好习惯,因为

a) 当线程收到通知时,它没有锁,在线程收到通知和它重新获取锁之间的时间里,系统的状态可能会由于其他线程的操作而改变(不是本例中的情况)和

b) 你不能依赖等待的终止意味着线程收到了通知。

通过上述更改,程序正常完成并显示以下输出:

Waiting for calculation
Total is:4950
Waiting for calculation
Total is:4950
Waiting for calculation
Total is:4950
Waiting for calculation
Total is:4950
Waiting for calculation
Total is:4950

完整修改后的代码如下:

public class Reader extends Thread {

Calculator c;

public Reader(Calculator cal) {
c=cal;
}

public void run (){
synchronized(c) {
try {
System.out.println("Waiting for calculation");
while (!c.finished) {
c.wait();
}
} catch (InterruptedException ex) {}
System.out.println("Total is:" +c.total);
}
}

public static void main (String[] a) {

Calculator calculator=new Calculator();
new Thread(calculator).start();

new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
new Reader(calculator).start();
}
}

class Calculator implements Runnable {

int total;
boolean finished;

public void run() {
synchronized(this) {
finished = false;
for(int i=0;i<100;i++) {
total=total+i;
}
notifyAll();
finished = true;
}
}
}

关于java - 如何进行线程交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37733823/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com