如何进入FutureTask执行状态?

Svi*_*len 5 java multithreading futuretask executors

我有一个singleThreadExecutor,以执行我按顺序提交给它的任务,即一个接一个的任务,没有并行执行.

我有runnable,这是这样的

MyRunnable implements Runnable {

@Override
public void run() {
    try {
        Thread.sleep(30000);
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    }
Run Code Online (Sandbox Code Playgroud)

}

例如,当我向上述单线程执行程序提交三个MyRunnable实例时,我希望第一个任务执行,因为Thread.sleep在TIMED_WAITING中有执行线程(我可能错误的具体州).其他两个任务不应该分配线程来执行它们,至少在第一个任务完成之前.

所以我的问题是如何通过FutureTask API获取此状态或以某种方式到达执行任务的线程(如果没有这样的线程然后任务等待执行或挂起)并获得其状态或者可能由某些其他方式?

FutureTask只定义了isCanceled()和isDone()方法,但这些方法还不足以描述Task的所有可能的执行状态.

Gre*_*tes 2

您可以添加一个getThread()方法来MyRunnable生成Thread执行该run()方法。

我建议添加一个像这样的实例变量(必须是易失性的以确保正确性):

 private volatile Thread myThread;
Run Code Online (Sandbox Code Playgroud)

在块之前执行此操作try

myThread = Thread.currentThread();
Run Code Online (Sandbox Code Playgroud)

并添加一个finally块:

myThread = null;
Run Code Online (Sandbox Code Playgroud)

然后你可以打电话:

final Thread theThread = myRunnable.getThread();
if (theThread != null) {
    System.out.println(theThread.getState());
}
Run Code Online (Sandbox Code Playgroud)

对于一些MyRunnable

null此时的结果不明确,意思是“尚未运行”或“已完成”。只需添加一个方法来告知操作是否已完成:

public boolean isDone() {
    return done;
}
Run Code Online (Sandbox Code Playgroud)

当然,您需要一个实例变量来记录此状态:

private volatile boolean done;
Run Code Online (Sandbox Code Playgroud)

并在块中将其设置为 true finally(可能在将线程设置为 之前null,那里存在一些竞争条件,因为有两个值捕获一个事物的状态。特别是,使用这种方法,您可以观察到isDone() == truegetThread() != null。您可以减轻这是通过拥有一个lock用于状态转换的对象并在更改一个或两个状态变量时对其进行同步来实现的):

done = true;
Run Code Online (Sandbox Code Playgroud)

请注意,仍然没有任何保护措施禁止单个线程MyRunnable同时提交给两个或多个线程。我知道你说你今天没有这样做:) 多个并发执行很可能会导致损坏的状态。您可以在 run 方法的开头放置一些互斥保护(例如简单地synchronizedrun()方法上写入),以确保在任何给定时间只发生一次执行。