最近我尝试了多线程,尝试让多个线程处理相同的事情,但只有在所有线程完成后才继续执行我的程序。我的代码太慢了(它实际上应该更快)并且我想知道是否有更高效和更快的方法来实现这一点:
我的可运行课程。对于某个任务,需要有一个新的Runnable,它扩展了这个Runnable并覆盖了doTask()。
public abstract class ParallelCappedRunnable implements Runnable {
private final Lock lock;
private final Condition condition;
private final ParallelCappedMultithreader pcm;
public ParallelCappedRunnable(ParallelCappedMultithreader pcm, Lock lock, Condition condition) {
this.lock = lock;
this.condition = condition;
this.pcm = pcm;
}
@Override
public final void run() {
doTask();
pcm.sendSignal();
if(pcm.getMissingSignals() == 0) {
lock.lock();
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
public abstract void doTask();
}
这个类启动许多新线程,只要有人在每个线程完成后调用start()和“调用结束”(idk如何调用它),它们都会在同一个任务上工作。
public class ParallelCappedMultithreader {
private AtomicInteger missingSignals = new AtomicInteger (0);
private final int MAX_THREADS;
private final Lock lock = new ReentrantLock();
private final Condition condition = lock.newCondition();
private final Class runnable, parentClass;
private final Object parentInstance;
public ParallelCappedMultithreader(Class<? extends ParallelCappedRunnable> runnable, int threads, Class parentClass, Object parentInstance) {
this.runnable = runnable;
this.parentClass = parentClass;
this.MAX_THREADS = threads;
this.parentInstance = parentInstance;
}
public ParallelCappedMultithreader(Class<? extends ParallelCappedRunnable> runnable, int threads) {
this(runnable, threads, null, null);
}
public void start() throws InterruptedException{
try {
missingSignals.set(MAX_THREADS);
Constructor constructor;
if(parentClass == null) {
constructor = runnable.getDeclaredConstructor(ParallelCappedMultithreader.class, Lock.class, Condition.class);
}
else {
constructor = runnable.getDeclaredConstructor(parentClass, ParallelCappedMultithreader.class, Lock.class, Condition.class);
}
for(int i = 0; i < MAX_THREADS; i++) {
if(parentClass == null)
(new Thread((Runnable)constructor.newInstance(this, lock, condition))).start();
else
(new Thread((Runnable)constructor.newInstance(parentInstance, this, lock, condition))).start();
}
} catch (Exception ex) {
Logger.getLogger(ParallelCappedMultithreader.class.getName()).log(Level.SEVERE, null, ex);
System.exit(0);
}
lock.lock();
try {
condition.await();
} finally {
lock.unlock();
}
}
public int getMissingSignals() {
return missingSignals.get();
}
public void sendSignal() {
System.out.println(missingSignals.getAndDecrement());
}
}
答案 0 :(得分:0)
您是否尝试过thread.join()?
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join%28%29
基本上你可以根据需要启动任意多个线程,并且“parent”在继续之前通过调用thread join()来等待“child”线程死亡。
答案 1 :(得分:0)
你有太多的事情发生了(以及所有的反思是什么)。您可以使用join
等待单个线程。如果你想等待多个线程,你可以这样做:
MyRunnable(List threads) {
lock (threads) {
threads.add(this);
}
}
void run() {
doStuff()
lock (threads) {
threads.remove(this);
if (threads.size() == 0)
threads.notify();
}
}
在经理班里面:
void startAndWait(int numThreads) {
List<MyRunnable> threads = new ArrayList<MyRunnable>();
for (int i=0; i<numThreads; i++)
new Thread(new MyRunnable(threads)).start();
lock (threads) {
while (threads.size() > 0)
wait();
}
}