【发布时间】:2018-02-18 18:24:58
【问题描述】:
我有多个线程粗略地计算给定数组的总和。我不能使用单独的工作线程和控制器,而是整个程序必须写在一个类中。该程序的重点是打印计算结果,线程 id 0 是第一个打印结果,然后是线程 id 1,然后是线程 id 2,依此类推。
我在类中编写了两个同步方法:finished - 在特定线程完成计算后通知所有线程,waitForThread - 如果 id 小于其自己的线程仍未完成,则等待。
因为我不能使用单独的控制器类,所以我决定创建一个静态数组doneArr,其中每个单元格代表一个线程ID,一旦线程完成其工作,它就会更新doneArr 中的相应单元格。这样waitForThread 就知道何时等待。
我似乎无法让它工作,你能指出正确的方向吗?
编辑:使用join() 可以轻松解决问题,但我正在寻找使用同步的解决方案。
这是代码:
public class WorkThread extends Thread {
private int[] vec;
private int id;
private int result;
private static int[] doneArr;
private static int progress = 0;
public WorkThread(int[] vec, int id) {
this.vec = vec;
this.id = id;
doneArr = new int[vec.length];
for(int i = 0; i < doneArr.length; i++) {
doneArr[i] = -1; //default value
}
}
private boolean finishedUpToMe() {
for(int i = 0; i < id; i++) {
if(doneArr[i] == -1)
return false;
}
return true;
}
private synchronized void waitForThread() throws InterruptedException {
while(!finishedUpToMe() && id > 0)
this.wait();
progress++;
}
private synchronized void finished() throws IllegalMonitorStateException {
this.notifyAll();
}
public int process(int[] vec, int id) {
int result = 0;
System.out.format("id = %d\n", this.id);
for(int i = 0; i < vec.length; i++) {
vec[i] = vec[i] + 1;
result = result + vec[i];
}
return result;
}
public void run() {
try {
this.waitForThread();
}catch (InterruptedException e) {
System.out.println("waitForThread exception");
}
result = process(vec, id);
doneArr[id] = id;
System.out.format("id = %d, result = %d\n", id, result);
try{
this.finished();
}catch (IllegalMonitorStateException e) {
System.out.format("finished exception\n");
}
}
public static void main(String[] args) {
int[] vec = {1,2,3,4};
WorkThread[] workers = new WorkThread[3];
for(int i = 0; i < workers.length; i++) {
workers[i] = new WorkThread(vec, i);
}
for(int i = 0; i < workers.length; i++) {
workers[i].start();
}
System.out.format("main\n");
}
}
【问题讨论】:
-
"整个程序必须在一个类中编写"....请问原因?为什么要摆出这么奇怪的限制来挑战自己?
-
这是一个非常奇怪的限制。但是,它实际上不应该有太大的区别,因为您不需要控制器来完成如此简单的任务。如果您真的想要一个,您可以简单地使用线程池或普通线程对象;它们都采用 runnables 或等效的 lambdas。基本上,您只需编写控制器类并让它分派工作人员,而不是像您那样对 Thread 进行子类化。
-
@user69513 这是我想要做的,在
process或run中编写所有逻辑,但我的同步不正常。 -
@Yos 没看太仔细,但是为什么每个线程都要单独初始化静态成员
doneArr呢? -
@user69513 因为我需要某种全局变量来跟踪哪些线程完成了他们的工作。
标签: java multithreading