【发布时间】:2014-11-22 21:06:07
【问题描述】:
我的代码如下:
WorkPool.java
import java.util.LinkedList;
/**
* Class that implements a work pool based on the model of "replicated workers"
* Tasks introduced in the work pool are objects of type MRCTask
*
*/
public class WorkPool {
int nThreads; //total number of worker threads
int nWaiting = 0; //number of worker threads blocked waiting for a task
public boolean ready = false; //problem is finished
LinkedList<MRCTask> tasks = new LinkedList<MRCTask>();
/**
* Constructor for class WorkPool.
* @param nThreads - number of worker threads
*/
public WorkPool(int nThreads) {
this.nThreads = nThreads;
}
/**
* Function which tries to obtain a task from the work pool
* If there are not available tasks, the function hangs until
* a task can be given or until the problem is finished
* @return A task to solve or null if the problem is finished
*/
public synchronized MRCTask getWork() {
if (tasks.size() == 0) { //empty work pool
nWaiting++;
/*
* finish condition:
* there is no available task in the work pool and no worker
* is active
*/
if (nWaiting == nThreads) {
ready = true;
/* problem is finished, announcing all workers */
notifyAll();
return null;
} else {
while (!ready && tasks.size() == 0) {
try {
this.wait();
} catch(Exception e) {e.printStackTrace();}
}
if (ready)
/* work is done */
return null;
nWaiting--;
}
}
return tasks.remove();
}
/**
* Function which inserts a task in the work pool
* @param sp The task which must be introduced
*/
synchronized void putWork(MRCTask sp) {
tasks.add(sp);
/* announcing one of the waiting workers */
this.notify();
}
}
TestMain.Java
public class TestMain {
public static void main(String[] args) throws InterruptedException {
int nr_proc = Runtime.getRuntime().availableProcessors();
WorkPool wp = new WorkPool(nr_proc);
MRCTask.t = 0;
for(int i = 0; i < 10000; i++)
wp.putWork(new MRCTask());
Worker[] wrk = new Worker[nr_proc];
for(int i = 0; i < nr_proc; i++)
wrk[i] = new Worker(wp);
for(int i = 0; i < nr_proc; i++)
wrk[i].start();
for(int i = 0; i < nr_proc; i++)
wrk[i].join();
System.out.println(MRCTask.t);
}
}
class Worker extends Thread {
WorkPool wp;
public Worker(WorkPool wp) {
this.wp = wp;
}
void work(MRCTask ps) throws Exception {
ps.processTask();
}
public void run() {
while (true) {
MRCTask ps = wp.getWork();
if (ps == null)
break;
try {
work(ps);
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
}
}
class MRCTask {
static int t;
public void processTask() {
t += 5;
}
}
运行此代码时,我通常期望得到 50000 作为答案。这只发生在 nr_proc 为 1 时。当 nr_proc 为 2 或 4(在我的情况下,availableProcessor() 返回 4)时,我得到随机值,例如 49960、49900、49995,有时甚至是 50000。 你能告诉我有什么问题吗? 在此先感谢并为这个巨大的代码感到抱歉! PS:我尝试修改函数 processTask() 如下:
public void processTask() {
synchronized(this) {
t += 5;
}
}
但是,我仍然遇到同样的问题。我认为同步部分会有所帮助,但事实并非如此。
【问题讨论】:
标签: java multithreading concurrency synchronized