多线程,计算正在运行的线程数

时间:2019-01-05 05:41:02

标签: java processing

我正在为跳棋建立RL ai(因此可能会运行许多不同的游戏),每个线程将单独运行一个游戏。我试图限制运行线程的数量。因此,如果正在运行的线程数量少于一定数量(threadAmount):则创建一个新线程并运行一个新游戏,否则:不执行任何操作并等待。

for (int i = 0; i < population.size(); i++) {
    int runningThreads = 0;
    for (int j = i; j < population.size(); j++) if (population.get(j).gameOver == false) runningThreads++; //for each running thread, add 1 to runningThreads
    if (runningThreads < threadAmount){ //threadAmount == max # of threads
      population.get(i).gameOver = false;
      Thread newThread = new Thread(population.get(i));
      newThread.start();
      println("\tnew thread started | "+runningThreads);
      delay(100);
    }
    else{
      i--; //retry this 
    }
  }

问题在于它只会创建所有线程,而println则显示“新线程已启动| 0” 25次,而runningThreads var在for循环中似乎没有增加根本就停留在0。不确定该怎么做:/,但是我知道这是Processing,而且它不是线程安全的,因此我准备拉一些花哨的东西来完成它。

2 个答案:

答案 0 :(得分:3)

如果我理解正确,那么这是您的要求:

  • 在单独的Thread中运行每个游戏。
  • 禁止同时运行超过n个游戏(或Thread个)。
  • 如果当前正在运行最大数量的游戏,请等到一个或多个完成后再运行新游戏。

最后一个要点尚不完全清楚。这可能意味着游戏应该排队等待执行,或者可能意味着调度Thread应该阻塞,直到“空间”可用为止。

在第一种情况(排队)中,可以使用配置为不超过n个线程的ExecutorService来解决。所有线程繁忙时提交的所有任务都将排队,直到一个线程可用为止。

ExecutorService executor = Executors.newFixedThreadPool(threadAmount);
for (Runnable r : population) {
    executor.execute(r);
}
executor.shutdown(); // If you won't be using it later

这还具有重复使用Thread实例而不是为每个游戏创建新的Thread的好处。

答案 1 :(得分:0)

正如我在评论中所说,这是一个代码示例,但是在c#中,我目前没有Java代码。但它应该类似地工作

List<Task> lTask = new List<Task>();

Worker w = new Worker(msg);
Task t = new Task(() => w.DoWork());
            t.Start();
            lTask.Add(t);`.

我将添加的任务保留在全局列表中。在计时器中,我会定期检查是否有任何任务(即线程)过期,

foreach(Task t in lTask)
                {
                    if (!t.Status.Equals(TaskStatus.Running))
                    {
                        // This thread is running... do whatever you do
                    }

                }

这就是我使用多线程并保持其生命日志的方式。