首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在线程中使用静态变量作为不同实例之间的通信

在线程中使用静态变量作为不同实例之间的通信
EN

Stack Overflow用户
提问于 2012-09-05 13:11:02
回答 4查看 115关注 0票数 1

我有一个多线程批处理应用程序,可以在5-10个并发执行线程之间的任何地方运行。它们的数据段被仔细地切片,以便尽可能均匀地分布,但当然,执行时间总是不同的。我想要做的是在最后一个线程结束时调用最后一种onFinalize方法,它将执行一些统计计算。

我想知道一个线程是否是最后一个线程的最好方法(而不是查询DB,这看起来有点乏味)是不是有一个静态变量,它会在添加新线程时在synchronized块中递增,在每个线程完成时递减。因此,当线程完成并执行递减时,我可以使用if来查看未完成的线程数是否为0,然后调用最终的统计数据。

我就是这么想的。我想知道是否有更好的、更优雅的或防弹的方法来实现这一点。

使用Java 7

谢谢

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-09-05 13:34:55

所以您还可以做的是创建一个ThreadManager类。这个类应该有一个List<Thread>。每当您创建一个新的Thread来执行您的任务时,您应该在ThreadManager中对其执行register。然后在ThreadManager中创建一个方法,该方法返回Listlive Threads的总number

通过这种方式,您可以随时查看有多少线程正在运行,还可以根据需要对正在运行的线程执行任何其他操作。另外,还应该定期运行另一个Thread,它应该从List中清除所有死线程引用。

示例ThreadManager可能如下所示:

代码语言:javascript
复制
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上执行其他功能。

票数 0
EN

Stack Overflow用户

发布于 2012-09-05 13:17:03

为什么不在最后对每个线程调用Thread.join()呢?你可以用一个for循环在每次运行时调用它-它会在第一次运行时锁定,然后当那一次运行完成时返回,然后你在下一次运行时锁定。当您退出循环时,它们都已退出。

代码语言:javascript
复制
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();
    }
}
票数 0
EN

Stack Overflow用户

发布于 2012-09-05 13:32:23

我通过创建一个框架来扩展基本的Runnable接口,以提供更健壮的线程架构,从而做了类似的事情。后来我发现,出于类似目的,它与GWT中的异步代码惊人地相似。

这是来自内存,但它基本上归结为:

代码语言:javascript
复制
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的能力,使我们能够利用许多线程安全的操作,并保证响应。

在实践中,实现只需覆盖AsyncRunnablerunAsync方法,并提供它们认为合适的任何AsyncCallback。重要的是要注意,在某些情况下,您实际上是为了简单地标记完成而使用它,在这种情况下,T可以是Void (如果您使用它,则可以是来自runAsyncreturn null)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12274821

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档