Java中的并发性——将任务委托给工作线程,我做得对吗?

Java中的并发性——将任务委托给工作线程,我做得对吗?,java,concurrency,executorservice,Java,Concurrency,Executorservice,所以我正在为一个在线游戏制作一个模拟器,我似乎想不出一个好方法来处理同时运行的大量任务。显然,在单个线程上加载所有内容都不起作用 我的想法是有一个主线程,将任务委托给x个工作线程。一旦主线程完成了对任务的排队,它就会向工作人员发出信号,让他们开始启动任务并停止,直到他们完成为止。我的执行情况如下: package com.rs2.engine; import java.util.concurrent.Executors; import java.util.concurrent.Executor

所以我正在为一个在线游戏制作一个模拟器,我似乎想不出一个好方法来处理同时运行的大量任务。显然,在单个线程上加载所有内容都不起作用

我的想法是有一个主线程,将任务委托给x个工作线程。一旦主线程完成了对任务的排队,它就会向工作人员发出信号,让他们开始启动任务并停止,直到他们完成为止。我的执行情况如下:

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());
    }

}
  • 在Engine类中,在并发性方面可以使用常规ArrayList吗
  • 是否有更好的方法将任务排队到Executor服务?我觉得如果同时有太多的任务排队,可能会导致问题
  • 在我开始重新发明轮子之前,有没有什么引擎框架我应该看看

  • 如果您担心在
    ExecutorService
    中排队的任务太多,可以使用
    信号灯来限制它一次可以运行的任务

    将其放入循环的
    processQueuedTasks()
    方法中,以限制要运行的任务数


    您可以设置线程池中的线程数,而不是使用
    信号量来限制并发运行的任务数。您将只获得与线程数量相同的并发运行任务

    Executors.newFixedThreadPool(n)

    public void queueTask(任务任务){

    由于此方法是公共的,可以从任何线程调用它,因此
    ArrayList
    将不会是线程安全的。请考虑如果在任务提交给执行器期间尝试对任务进行排队,会发生什么情况。您从线程池执行器“借用”了功能,并通过将其集合放入代码中任务。

    可能属于该方法的任务只能从主线程调用,所以我不关心这一点。我只是不认为在这种情况下我应该使用ArrayList。