多线程等待完成

时间:2014-04-16 21:35:12

标签: java

最近我尝试了多线程,尝试让多个线程处理相同的事情,但只有在所有线程完成后才继续执行我的程序。我的代码太慢了(它实际上应该更快)并且我想知道是否有更高效和更快的方法来实现这一点:

我的可运行课程。对于某个任务,需要有一个新的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());

}
}

2 个答案:

答案 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”线程死亡。

Java: How to use Thread.join

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