简体   繁体   English

从可运行线程返回值

[英]Return value from Runnable Thread

There are N thread and each thread sets status to 0 or 1 in its own member variable "status". 有N个线程,每个线程在其自己的成员变量“ status”中将状态设置为0或1。 In caller, if any one thread has 1 as status, overall status has to become 1. 在调用方中,如果任何一个线程的状态为1,则总体状态必须为1。

These threads run in batch mode. 这些线程以批处理模式运行。 So if any fails all need to be run again. 因此,如果有任何失败,都需要再次运行。 I need to come up with some Handling for handling failure such that remaining threads also halt immediately. 我需要提出一些处理失败的处理方法,以使其余线程也立即停止。

The Threads are Runnable however, not Callable. 线程是可运行的,但是不是可调用的。

We can communicate between threads using a volatile boolean variable to signal failure. 我们可以使用易失的布尔变量在线程之间进行通信,以发出故障信号。 However, I needed to know how to read individual status from runnable threads in caller. 但是,我需要知道如何从调用者的可运行线程中读取单个状态。

Theres several ways to accomplish this, I'm sure. 我敢肯定,有几种方法可以做到这一点。 One way is to use a completion service. 一种方法是使用完成服务。 Here's some (roughly tested) code: 这是一些(经过严格测试的)代码:

public void allSucceed(final List<MyRunnable> tasks) {
    if (tasks == null || tasks.size() == 0)
        return;

    int status = 0;

    boolean success = true;
    do {
        final ExecutorService executorService = Executors
                .newFixedThreadPool(tasks.size());
        final CompletionService<MyRunnable> completionService = new ExecutorCompletionService<MyRunnable>(
                executorService);
        for (final MyRunnable task : tasks) {
            completionService.submit(task, task);
        }

        for (int i = 0; i < tasks.size(); i++) {
            try {
                status = completionService.take().get().getStatus();
            } catch (final Exception e) {
                success = false;
                break;
            }

            if (status == 0) {
                System.out.println("A task failed. All will be rerun");
                executorService.shutdownNow();
                success = false;
                break;
            }
        }
    } while (!success);
}

It's critical that you design your tasks (Runnables) to be interruptible, or else any attempt to halt them will be futile. 将任务(可运行对象)设计为可中断的至关重要,否则任何停止任务的尝试都是徒劳的。

You can simply ask the threads set a value in the caller's thread: 您可以简单地要求线程在调用者的线程中设置一个值:

Field in caller: 来电者字段:

int[] status = new int[NUM_THREADS];

Then give an index to each Runnable so it can set its status in the array, for example: 然后为每个Runnable提供一个索引,以便它可以在数组中设置其状态,例如:

for (int i = 0; i < NUM_THREADS; i++) {
    final index = i;

    Runnable r = new Runnable() {
        void run() {
            // have your code stop occasionally to check for any failures
            if (>I failed>)
                status[index] = 1;
        }
    }
    // start thread using Runnable
}

To detect halting, have your Runnables occasionally check for any failures in the arraym or you could have add separate boolean flag to your caller class: 要检测停止,请让您的Runnables偶尔检查arraym中是否有任何失败,或者您可以在调用者类中添加单独的boolean标志:

volatile boolean failed = false;
Object lock = new Object();

then in your runnables: 然后在您的可运行物品中:

if (<I failed>) {
    synchronised (lock) {
        failed = true;
    }
}

and your check for failure during the work would be: 您在工作过程中是否失败的检查将是:

synchronised (lock) {
    if (failed) {
        // clean up resources
        status[index] = -1; // consider using a separate value for "halted"
        return;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM