gpt4 book ai didi

Java 多线程 - 从列表中删除项目

转载 作者:行者123 更新时间:2023-12-01 18:00:50 24 4
gpt4 key购买 nike

刚接触多线程,请耐心等待。我正在尝试运行 2 个线程,从任务列表中删除项目(总共 10 个任务),直到任务列表为空。

到目前为止我所拥有的是:

主要方法:

public static void main(String[] args) {


List<Task> taskList = new ArrayList<Task>();
List<Thread> threadList = new ArrayList<Thread>();


for (int i = 1; i <= 10; i++) {

taskList.add(new Task("some details");
}

TaskManager manager = new TaskManager();
gestor.setTaskList(taskList);

Thread t1 = new Thread(taskManager);
Thread t2 = new Thread(taskManager);

threadList.add(t1);
threadList.add(t2);

if(threadList.size() > 0){
for (Thread thread : threadList){
thread.start();
}
}

for (Thread thread : threadList){
try {
thread.join();
} catch (InterruptedException e) {
System.out.println("thread " + Thread.currentThread().getName() + " was interrupted");
}
}

System.out.println("END OF MAIN");

}

任务管理器类:

public class TaskManager implements Runnable {

private List<Task> availableTasks;
private Random random = new Random();

public void setAvailableTasks(List<Task> availableTasks) {
this.availableTasks = availableTasks;
}

@Override
public void run() {
while (!availableTasks.isEmpty()) {
takeTask();
}
}

public void takeTask() {
try {
Thread.sleep(1000);
int index = random.nextInt(availableTasks.size());
Task task = availableTasks.get(index);

printDetails(task);
availableTasks.remove(task);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

public void printDetails(Task task) {
//here it should print the details to the console
}
}

问题是,它要么运行 2 次,要么总是同一个线程运行 10 次。我知道这可能是一个愚蠢的问题,但我希望有人能澄清它!提前致谢

编辑:我能够使用@Lidae的建议使其工作

将任务方法编辑如下:

public void takeTask() {
try {
Thread.sleep(1000);
synchronized (this) {
if (!availableTasks.isEmpty()) {
int index = random.nextInt(availableTasks.size());
Task task = availableTasks.get(index);

printDetails(task);
availableTasks.remove(task);
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

最佳答案

由于多个线程尝试同时访问同一对象,您的代码存在一些并发问题。例如,可能发生的一件事是线程 A 从列表中获取一个任务(在 Task task = availableTasks.get(index) 中),然后发生上下文切换,并且该任务被删除线程 B,当线程 A 尝试删除该任务时,它已经消失了(这不会在您的代码中导致异常,但无论如何它都可能很糟糕,具体取决于您计划对任务执行什么操作)。

当您尝试从中获取任务时,您也无法确定列表不为空:当它最后一次在 while 循环中检查时它是空的,但从那时到它尝试执行的时间之间一个任务,另一个线程可能已经完成了最后一个任务。即使您删除对 Thread.sleep 的调用也是如此。

您需要确保 availableTasks 列表一次只能由一个线程修改。这可以通过多种方式完成,例如通过使用信号量,或通过在共享数据对象中使用同步方法。

关于Java 多线程 - 从列表中删除项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41079818/

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