关闭。这个问题需要details or clarity .它目前不接受答案。
想改进这个问题?通过 editing this post 添加详细信息并澄清问题.
2年前关闭。
Improve this question
我正在尝试在 java 中设计一个线程池。根据我的设计,我在主运行器线程类中使用 java 的 Linkedlist DS 来保留所有提交的任务。此任务列表正在从主类更新,其中主类正在将任务添加到任务列表。在我的主运行线程中,我正在运行一个 while 循环并不断检查 LinkedList 是否不为空,如果它包含一个任务,那么我正在检索该任务并执行它。
这里的问题是我已经从我的主方法中添加了一个任务到任务列表中,当我打印任务列表对象的大小时,我可以看到这个任务列表的大小是主方法中的 1,但是在运行器线程中,它显示为0。
需要帮助弄清楚这里到底发生了什么。
public class ReusableThread<T> extends Thread{
private volatile Queue<Work<T>> tasks = new LinkedList<Work<T>>();
private Work<T> currentWork;
private class Work<T>{
Result<T> result;
Taskable<T> task;
public Work(Result<T> result, Taskable<T> task) {
this.result = result;
this.task = task;
}
}
@Override
public void run() {
while(true){
//System.out.println("ReusableThread.run()");
System.out.println("Inside thread : " + getTasks().size()); //This print 0
if(!tasks.isEmpty()){
currentWork = getWork();
T value = currentWork.task.run();
//currentWork.result.setValue(currentWork.task.run());
}
//currentWork.result.setComplete(true);
}
}
public Work<T> getWork() {
return tasks.remove();
}
public Queue<Work<T>> getTasks() {
return tasks;
}
public Result<T> submit(Taskable<T> task) {
Result<T> result = new Result<T>();
this.tasks.add(new Work<T>(result, task));
return result;
}
}
主线程如下:
public void test() throws InterruptedException {
int count = 0;
ReusableThread<Integer> rt = new ReusableThread();
rt.start();
Thread.sleep(1000);
System.out.println("Thread-"+ count +" starting");
Result<Integer> result = rt.submit(JavaUtils::task);
System.out.println("In main : " + rt.getTasks().size()); //This prints 1
}
最佳答案
我认为存在线程安全问题。具体来说:
LinkedList
不是线程安全的,LinkedList
rt.getTasks().size()
中的对象没有任何同步。 这足以导致
size()
在某些情况下返回一个陈旧的值。如果你要依赖
volatile
的语义您需要对对线程安全很重要的每个写入/读取序列的发生前关系进行适当的分析。这很棘手。我的建议是:
volatile
.使用synchronized
和/或现有的线程安全数据结构......如果您需要重新发明轮子。 Executors.singleThreadExecutor
;见 javadoc . 关于java - 线程池任务列表更新问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59538846/