我有一个多线程批处理应用程序,可以在5-10个并发执行线程之间的任何地方运行。它们的数据段被仔细地切片,以便尽可能均匀地分布,但当然,执行时间总是不同的。我想要做的是在最后一个线程结束时调用最后一种onFinalize方法,它将执行一些统计计算。
我想知道一个线程是否是最后一个线程的最好方法(而不是查询DB,这看起来有点乏味)是不是有一个静态变量,它会在添加新线程时在synchronized块中递增,在每个线程完成时递减。因此,当线程完成并执行递减时,我可以使用if来查看未完成的线程数是否为0,然后调用最终的统计数据。
我就是这么想的。我想知道是否有更好的、更优雅的或防弹的方法来实现这一点。
使用Java 7
谢谢
发布于 2012-09-05 13:34:55
所以您还可以做的是创建一个ThreadManager类。这个类应该有一个List<Thread>。每当您创建一个新的Thread来执行您的任务时,您应该在ThreadManager中对其执行register。然后在ThreadManager中创建一个方法,该方法返回List中live Threads的总number。
通过这种方式,您可以随时查看有多少线程正在运行,还可以根据需要对正在运行的线程执行任何其他操作。另外,还应该定期运行另一个Thread,它应该从List中清除所有死线程引用。
示例ThreadManager可能如下所示:
public class ThreadManager {
private static ThreadManager tm;
private List<Thread> threads;
public static ThreadManager get() {
if(null == tm) {
tm = new ThreadManager();
}
return tm;
}
private ThreadManager() {
threads = new ArrayList<Thread>();
}
public int getCountOfAliveThreads() {
int count = 0;
for(Thread t : threads) {
if(t.isAlive()) {
count++;
}
}
return count;
}
}希望这能有所帮助。您还可以在Thread List上执行其他功能。
发布于 2012-09-05 13:17:03
为什么不在最后对每个线程调用Thread.join()呢?你可以用一个for循环在每次运行时调用它-它会在第一次运行时锁定,然后当那一次运行完成时返回,然后你在下一次运行时锁定。当您退出循环时,它们都已退出。
public class ThreadManager {
private List<Thread> threads;
public void addThread(Thread thread) {
threads.add(thread);
}
public void waitTillAllComplete() {
for (int ind=0; ind<threads.size(); ind++)
threads.get(ind).join();
}
}发布于 2012-09-05 13:32:23
我通过创建一个框架来扩展基本的Runnable接口,以提供更健壮的线程架构,从而做了类似的事情。后来我发现,出于类似目的,它与GWT中的异步代码惊人地相似。
这是来自内存,但它基本上归结为:
public interface AsyncRunnable<T> extends Runnable
{
AsyncCallback<T> getCallback();
T runAsync();
}
public interface AsyncCallback<T>
{
void onSuccess(T data);
void onFailure(Exception exception);
}
public interface AsyncCallbackInvoker<T> extends Runnable
{
// implies requirement for callback...
AsyncCallback<T> getCallback();
}
public class SuccessfulAsyncCallbackInvoker<T> implements AsyncCallback<T>
{
private final AsyncCallback<T> callback;
private final T data;
public SuccessfulAsyncCallbackInvoker(AsyncCallback<T> callback, T data)
{
// note: data being null may be valid; callback would not be
this.callback = callback;
this.data = data;
}
@Override
public void run()
{
callback.onSuccess(data);
}
@Override
public AsyncCallback<T> getCallback()
{
return callback;
}
}
public class FailureAsyncCallbackInvoker<T> implements AsyncCallback<T>
{
private final AsyncCallback<T> callback;
private final Exception exception;
public FailureAsyncCallbackInvoker(AsyncCallback<T> callback, Exception exception)
{
// note: data being null may be valid; callback would not be
this.callback = callback;
this.exception= exception;
}
@Override
public void run()
{
callback.onFailure(exception);
}
@Override
public AsyncCallback<T> getCallback()
{
return callback;
}
}
public abstract class AbstractAsyncRunnable<T> implements AsyncRunnable<T>
{
private final AsyncCallback<T> callback;
public AbstractAsyncRunnable(AsyncCallback<T> callback)
{
// if == null -> throw
this.callback = callback;
}
@Override
public /* final */ void run()
{
AsyncCallbackInvoker<T> invoker;
try
{
T data = runAsync();
invoker = new SuccessfulAsyncCallbackInvoker<T>(callback, data);
}
catch (Exception e)
{
invoker = new FailureAsyncCallbackInvoker<T>(callback, e);
}
invokeCallback(invoker);
}
// allows overriding to put callback on whatever Thread you want
protected void invokeCallback(AsyncCallbackInvoker<T> invoker)
{
invoker.run();
}
}在实践中,它已经被证明是令人难以置信的健壮的,特别是通过提供覆盖invokeCallback的能力,使我们能够利用许多线程安全的操作,并保证响应。
在实践中,实现只需覆盖AsyncRunnable的runAsync方法,并提供它们认为合适的任何AsyncCallback。重要的是要注意,在某些情况下,您实际上是为了简单地标记完成而使用它,在这种情况下,T可以是Void (如果您使用它,则可以是来自runAsync的return null)。
https://stackoverflow.com/questions/12274821
复制相似问题