问题描述
我有一个singleThreadExecutor,以便按顺序执行我提交给它的任务,即一个接一个的任务,没有并行执行。
I have a singleThreadExecutor in order to execute the tasks I submit to it in serial order i.e. one task after another, no parallel execution.
我已经运行了类似这样的事情
I have runnable which goes something like this
MyRunnable implements Runnable {
@Override
public void run() {
try {
Thread.sleep(30000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
例如,当我向上述单线程执行程序提交三个MyRunnable实例时,我希望第一个任务执行,因为Thread.sleep在TIMED_WAITING中有执行线程(我可能错误的具体州)。其他两个任务不应该分配执行它们的线程,至少在第一个任务完成之前不会。
When I submit ,for example, three instances of MyRunnable to the afore-mentioned single thread executor, I would expect to have the first task executing and because of the Thread.sleep has Its executing thread in TIMED_WAITING (I may be wrong about the specific state). The other two tasks should not have threads assigned to execute them, at least not until the first task has finished.
所以我的问题是如何通过FutureTask获取这个状态API或以某种方式到达正在执行任务的线程(如果没有这样的线程,那么任务等待执行或挂起)并获得其状态或者通过其他方式?
So my question is how to get this state via the FutureTask API or somehow get to the thread that is executing the task (if there is no such thread then the task is waiting to be executed or pending) and get Its state or perhaps by some other means?
FutureTask只定义了isCanceled()和isDone()方法,但这些方法还不足以描述Task的所有可能的执行状态。
FutureTask only defines isCanceled() and isDone() methods, but those are not quite enough to describe all the possible execution statuses of the Task.
推荐答案
您可以将 getThread()
方法添加到 MyRunnable
生成 Thread
执行 run()
方法。
You could add a getThread()
method to MyRunnable
that produces the Thread
executing the run()
method.
我建议像这样添加一个实例变量(必须以确保正确性):
I would suggest adding an instance variable like this (must be volatile to ensure correctness):
private volatile Thread myThread;
在尝试
块之前执行此操作:
myThread = Thread.currentThread();
并使用以下内容添加 finally
块:
And add a finally
block with this:
myThread = null;
然后你可以打电话:
final Thread theThread = myRunnable.getThread();
if (theThread != null) {
System.out.println(theThread.getState());
}
某些 MyRunnable
。
null
此时是一个模棱两可的结果,意思是还没有运行或已经完成了。只需添加一个方法,告诉操作是否已完成:
null
is an ambiguous result at this point, meaning either, "hasn't run," or "has completed." Simply add a method that tells whether the operation has completed:
public boolean isDone() {
return done;
}
当然,你需要一个实例变量来记录这个状态: / p>
Of course, you'll need an instance variable to record this state:
private volatile boolean done;
并在 finally
中将其设置为true阻止(可能在将线程设置为 null
之前,那里有一些竞争条件,因为有两个值捕获一件事的状态。特别是,使用这种方法你可以观察 isDone()== true
和 getThread()!= null
。你可以通过 lock
状态转换的对象,并在更改一个或两个状态变量时对其进行同步):
And set it to true in the finally
block (probably before setting the thread to null
, there's a bit of a race condition there because there are two values capturing the state of one thing. In particular, with this approach you could observe isDone() == true
and getThread() != null
. You could mitigate this by having a lock
object for state transitions and synchronize on it when changing one or both state variables):
done = true;
请注意,仍然没有任何警卫禁止单个 MyRunnable
从并发提交到两个或多个线程。我知道你说你今天没有这样做......今天多个并发执行会导致状态损坏,可能性很高。您可以在开头的时候在 run()
方法中放置一些相互排斥的保护(例如简单地写 synchronized
) run方法,确保在任何给定时间只发生一次执行。
Note that there still isn't any guard that prohibits a single MyRunnable
from being submitted concurrently to two or more threads. I know you say that you're not doing this... today :) Multiple concurrent executions will lead to corrupted state with high likelihood. You could put some mutual exclusive guard (such as simply writing synchronized
on the run()
method) at the beginning of the run method to ensure that only a single execution is happening at any given time.
这篇关于如何进入FutureTask执行状态?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!