Java中的并发性——将任务委托给工作线程,我做得对吗?
所以我正在为一个在线游戏制作一个模拟器,我似乎想不出一个好方法来处理同时运行的大量任务。显然,在单个线程上加载所有内容都不起作用 我的想法是有一个主线程,将任务委托给x个工作线程。一旦主线程完成了对任务的排队,它就会向工作人员发出信号,让他们开始启动任务并停止,直到他们完成为止。我的执行情况如下:Java中的并发性——将任务委托给工作线程,我做得对吗?,java,concurrency,executorservice,Java,Concurrency,Executorservice,所以我正在为一个在线游戏制作一个模拟器,我似乎想不出一个好方法来处理同时运行的大量任务。显然,在单个线程上加载所有内容都不起作用 我的想法是有一个主线程,将任务委托给x个工作线程。一旦主线程完成了对任务的排队,它就会向工作人员发出信号,让他们开始启动任务并停止,直到他们完成为止。我的执行情况如下: package com.rs2.engine; import java.util.concurrent.Executors; import java.util.concurrent.Executor
package com.rs2.engine;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.CountDownLatch;
import java.util.ArrayList;
import com.rs2.util.Timer;
public class Engine implements Runnable {
private ScheduledExecutorService scheduledExecutorService;
private ExecutorService executorService;
private int currentTick;
private ArrayList<Task> tasks;
private Timer timer;
public Engine(int workers) {
this.executorService = Executors.newFixedThreadPool(workers);
this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
this.currentTick = 0;
this.tasks = new ArrayList<>(10000);
this.timer = new Timer();
}
public int getCurrentTick() {
return currentTick;
}
public ExecutorService getWorkers() {
return executorService;
}
public void start() {
this.scheduledExecutorService.scheduleAtFixedRate(this, 0, 600, TimeUnit.MILLISECONDS);
}
public void cycle() {
}
public void queueTask(Task task) {
tasks.add(task);
}
public void processQueuedTasks() {
try {
CountDownLatch latch = new CountDownLatch(tasks.size());
for (int i = 0; i < tasks.size(); i++) {
Task t = tasks.get(i);
t.setCountDownLatch(latch);
executorService.submit(t);
}
latch.await();
tasks.clear();
} catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
timer.reset();
cycle();
currentTick++;
//System.out.println("Cycle time: "+timer.elapsed());
}
}
我的问题如下:
package com.rs2.engine;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.CountDownLatch;
import java.util.ArrayList;
import com.rs2.util.Timer;
public class Engine implements Runnable {
private ScheduledExecutorService scheduledExecutorService;
private ExecutorService executorService;
private int currentTick;
private ArrayList<Task> tasks;
private Timer timer;
public Engine(int workers) {
this.executorService = Executors.newFixedThreadPool(workers);
this.scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
this.currentTick = 0;
this.tasks = new ArrayList<>(10000);
this.timer = new Timer();
}
public int getCurrentTick() {
return currentTick;
}
public ExecutorService getWorkers() {
return executorService;
}
public void start() {
this.scheduledExecutorService.scheduleAtFixedRate(this, 0, 600, TimeUnit.MILLISECONDS);
}
public void cycle() {
}
public void queueTask(Task task) {
tasks.add(task);
}
public void processQueuedTasks() {
try {
CountDownLatch latch = new CountDownLatch(tasks.size());
for (int i = 0; i < tasks.size(); i++) {
Task t = tasks.get(i);
t.setCountDownLatch(latch);
executorService.submit(t);
}
latch.await();
tasks.clear();
} catch(Exception e) {
e.printStackTrace();
}
}
@Override
public void run() {
timer.reset();
cycle();
currentTick++;
//System.out.println("Cycle time: "+timer.elapsed());
}
}
如果您担心在
ExecutorService
中排队的任务太多,可以使用信号灯来限制它一次可以运行的任务
将其放入循环的processQueuedTasks()
方法中,以限制要运行的任务数
您可以设置线程池中的线程数,而不是使用信号量来限制并发运行的任务数。您将只获得与线程数量相同的并发运行任务
Executors.newFixedThreadPool(n)代码>
public void queueTask(任务任务){
由于此方法是公共的,可以从任何线程调用它,因此ArrayList
将不会是线程安全的。请考虑如果在任务提交给执行器期间尝试对任务进行排队,会发生什么情况。您从线程池执行器“借用”了功能,并通过将其集合放入代码中任务。可能属于该方法的任务只能从主线程调用,所以我不关心这一点。我只是不认为在这种情况下我应该使用ArrayList。