java 并行运行 100 个线程,如果前面的一些线程完成,则运行丢失的线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5508563/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 11:27:53  来源:igfitidea点击:

Run 100 threads in parallel and run missing threads if some previous are finished

javamultithreadingparallel-processing

提问by Clark

For example I need to always run 100 threads to do some action. I have class which called ThreadsWorkerwhich looks for threads count and runs missing threads if some previous are finished. So, this is the table which describes situation:

例如,我需要始终运行 100 个线程来执行某些操作。我有一个类,ThreadsWorker它会查找线程数并在某些先前完成时运行丢失的线程。所以,这是描述情况的表格:

1 second: 100 threads
2 second: 92 threads (ThreadsWorker generates new 8 threads)
3 second: 100 theads
4 second: 72 threads (ThreadsWorker generates 28 threads)

And so on. My threads are anonymous calls (just new Thread(new Runnable(...)).start()) because I don't know how to correctly save them to Threads[]array because, while ThreadsWorkerwill save threads[i] = new Threads(), some threads may be finished and then there will be some collision with array indexes.

等等。我的线程是匿名调用(只是new Thread(new Runnable(...)).start()),因为我不知道如何正确地将它们保存到Threads[]数组中,因为虽然ThreadsWorker会保存threads[i] = new Threads(),但某些线程可能会完成,然后会与数组索引发生一些冲突。

Because of anonymous calls I use threadsCountvariable now and increment it in threads body beginning and decrements in threads body end (using synchronized). Okay, it works correctly and my single way is to use while()loop which checks if threadsCount == 0when the progress is complete.

由于匿名调用,我threadsCount现在使用变量并在线程主体开始时增加它,在线程主体结束时减少它(使用synchronized)。好的,它工作正常,我的唯一方法是使用while()循环来检查threadsCount == 0进度是否完成。

I think that this is C-style but not Java-way :) So, can you help me to do it in Java-way?

我认为这是 C 风格而不是 Java 方式 :) 那么,你能帮我用 Java 方式做吗?

回答by Michael Brewer-Davis

If your goal is simply to have 100 threads actively processing, I suggest looking at Java thread pools(and Executorsmore generally).

如果您的目标只是让 100 个线程主动处理,我建议查看 Java线程池(以及更普遍的Executors)。

I'm unclear as to whether you want to keep all 100 threads going or wait for them all to finish. Your question references both (ThreadsWorker spawning 28 new threads, threadsCount==0) and they seem contradictory.

我不清楚您是要保持所有 100 个线程继续运行还是等待它们全部完成。您的问题同时引用了(ThreadsWorker 产生了 28 个新线程,threadsCount==0)并且它们似乎相互矛盾。

回答by squawknull

Put all the threads into an array or collection.

将所有线程放入一个数组或集合中。

Then loop through the collection calling Thread.join() on each. When this loop completes, all threads are done.

然后循环遍历每个调用 Thread.join() 的集合。当这个循环完成时,所有线程都完成了。

ArrayList threads = new ArrayList();
for (int i = 0; i < 5; i++) {
  Thread t = new AweseomeThread();
  t.start();
  threads.add(t);
}

for (Thread t : threads) {
  t.join();
}

You'll need some exception handling too (such as InterruptedException). But, I'll leave that as an exercise for the reader... :)

您还需要一些异常处理(例如 InterruptedException)。但是,我将把它留给读者作为练习...... :)

回答by store88

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/CountDownLatch.html

You can try class CountDownLatchjdk api

你可以试试class CountDownLatchjdk api

private CountDownLatch latch;
private static class SimpleThread extends Thread {
 public void run() {
  latch.countDown();
 }
}
public static void main(String[] args) {
 int threadcount = 10;
 latch = new CountDownLatch(threadcount);
 for (int i = 0; i < 10; i++) {
  Thread t = new SimpleThread();
  t.start();
 }
 // waiting threads all finished
 latch.await();
}

Fetch the thread count from attibute latchof the Main class

latchMain 类的属性中获取线程数

回答by richs

I believe you are trying to have ThreadWorker submit new threads for all thread that have been completed.

我相信您正试图让 ThreadWorker 为所有已完成的线程提交新线程。

I'd use a BlockingQueue that threads (Your Runnable(s)) add to when complete. ThreadWorker will wait until a thread completes and then will start a new thread.

我会使用一个 BlockingQueue,线程(您的 Runnable(s))在完成时添加到该队列中。ThreadWorker 将等待直到一个线程完成,然后将启动一个新线程。

public class YourRunnable implements Runnable {
  private final BlockingQueue<YourRunnable> queue;
  public YourRunnable(BlockingQueue<YourRunnable> queue){
    this.queue = queue;
  }
  public void run{
      // Your Code...
      // Finished Processing
      queue.add(this);
  }
}
public class ThreadWorkder implements Runnable { 
  private final BlockingQueue<YourRunnable> queue;
  ThreadWorker(BlockingQueue<YourRunnable> queue){
    this.queue = queue;
  }
  public void run{
    while(queue.take()){
       (new Thread(new YourRunnable(queue))).start();
    }
  }
  // general main method
  public static void main(String [] args){
    BlockingQueue<YourRunnable> queue = new LinkedBlockingQueue<YourRunnable>();
    ThreadWorker worker = new ThreadWorker(queue);
    Thread(worker).start();
    for (int i = 0; i < 100; i++){
      (new Thread(new YourRunnable(queue))).start();
    }
  }
}

回答by squawknull

Use a collection instead of an array. As the threads are completed, have them remove themselves from the array. Something like this:

使用集合而不是数组。当线程完成时,让它们从数组中移除自己。像这样的东西:

public class Foo {
  Vector<Thread> threads = new Vector<Thread>(); //Vector is threadsafe

  public ensureThreadCount(int count) {
    while (threads.size() < count) {
      Thread t = new AweseomeThread(threads);
      threads.add(t);
      t.start();
    }
  }
}

public class AwesomeThread {
  Collection threads;
  public AwesomeThread(Collection threads) {
    this.threads = threads;
  }

  public void run() {
    try {
      // do stuff
    } catch (Throwable t) {
    } finally {
      threads.remove(this);
    }
  }
}

Then, have your worker just call Foo.ensureThreadCount().

然后,让您的工作人员调用 Foo.ensureThreadCount()。