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
Run 100 threads in parallel and run missing threads if some previous are finished
提问by Clark
For example I need to always run 100 threads to do some action.
I have class which called ThreadsWorker
which 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 ThreadsWorker
will 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 threadsCount
variable 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 == 0
when 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 CountDownLatch
jdk api
你可以试试class CountDownLatch
jdk 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 latch
of the Main class
从latch
Main 类的属性中获取线程数
回答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()。