【发布时间】:2020-07-08 16:51:22
【问题描述】:
我为我正在制作的项目尝试了多线程。在项目中,每次调用某个函数时,我都需要多次进行某个计算。我尝试制作一些测试代码来了解如何做,但我无法让它正常工作(当我调试它时,代码似乎工作得很好,但如果我正常运行它,它在第一个周期之后就无法工作)。
在代码中有一个无限循环,它模仿我的项目多次调用函数。我尝试这样做,以便线程在 changeflag 为真时运行,并在每次计算运行后将标志更改为假,这样它就会停止一次又一次地计算它,并且在“调用”函数后我将其更改为真,所以它可以再次计算。
以下是我的代码:
import java.util.ArrayList;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.SynchronousQueue;
public class Main {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Result> queue = new SynchronousQueue<>();
int loops = 0;
MyThread[] arr = new MyThread[10];
ArrayList<Result> ress = new ArrayList<>();
for (int i = 0; i < arr.length; i++) {
arr[i] = new MyThread(i, queue);
arr[i].start();
}
while (true) {
System.out.println(loops++);
while (ress.size() < arr.length){
ress.add(queue.take());
}
while (!ress.isEmpty()){
arr[ress.get(0).getSign()].setChangeflag(true);
ress.remove(0);
}
}
}
}
import java.util.Random;
import java.util.concurrent.BlockingQueue;
public class MyThread extends Thread{
private boolean changeflag = true;
private boolean runflag = true;
private int sign;
private BlockingQueue<Result> queue;
Random rnd = new Random();
public MyThread(int sign, BlockingQueue<Result> queue){
this.sign = sign;
this.queue = queue;
}
public void run(){
while (runflag){
if(changeflag){
changeflag = false;
try {
queue.put(sense());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public Result sense(){
return new Result( rnd.nextInt(10), sign);
}
public synchronized void setChangeflag(boolean changeflag) {
this.changeflag = changeflag;
}
}
public class Result {
private double res;
private int sign;
public Result(double res, int sign) {
this.res = res;
this.sign = sign;
}
public int getSign() {
return sign;
}
}
【问题讨论】:
-
"当我调试它时,代码似乎运行良好,但如果我正常运行它,它在第一个周期之后就无法运行" 欢迎使用并发!我不太明白你想用这段代码实现什么。你能解释一下你的目标是什么吗?为什么不直接运行一个线程来计算结果(或使用线程池)?
-
我试图做到这一点,所以每次调用某个函数时,我都会得到一组新的结果。在我的实际代码中, sense() 不返回随机数,而是进行一定的计算,除非内容发生变化,否则我不希望它进行该计算。 @m0skit0
-
@m0skit0 我假设您没有收到我的回复通知。所以我正在尝试再次 ping 你。非常感谢您的帮助!
-
第一次收到但是忘记回复了,不好意思。如果这就是你想要的,那么 run() 方法中的 while 有什么用?为什么要在那里循环?为什么还有阻塞队列?
-
我的朋友建议这样做。我基本上保持线程运行,但在调用上述函数时更改更改标志,以便它再次运行计算。并且阻塞队列是这样的,主线程将等待所有计算完成,直到它继续。如果您有更好的建议,请全神贯注!就像我说的,我是线程新手,这就是我的朋友建议我这样做的方式。 @m0skit0
标签: java multithreading