当前位置: 首页 > 面试题库 >

如何进入FutureTask执行状态?

巫马庆
2023-03-14
问题内容

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

我有可运行的东西,像这样

MyRunnable implements Runnable {

@Override
public void run() {
    try {
        Thread.sleep(30000);
    } catch (InterruptedException e1) {
        e1.printStackTrace();
    }

}

例如,当我向上述单线程执行器提交MyRunnable的三个实例时,我希望执行第一个任务,并且由于Thread.sleep在TIMED_WAITING中具有其执行线程(我可能对特定的线程有误州)。其他两个任务不应分配有执行它们的线程,至少直到第一个任务完成时才分配线程。

所以我的问题是如何通过FutureTask
API来获得此状态,或者以某种方式到达正在执行任务的线程(如果没有这样的线程,则该任务正在等待执行或挂起)并获得其状态,或者通过某种方式其他手段?

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


问题答案:

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

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

 private volatile Thread myThread;

try块之前执行此操作:

myThread = Thread.currentThread();

并添加一个代码finally块:

myThread = null;

然后您可以致电:

final Thread theThread = myRunnable.getThread();
if (theThread != null) {
    System.out.println(theThread.getState());
}

对于一些MyRunnable

null在这一点上是不确定的结果,表示“未运行”或“已完成”。只需添加一个方法来告知操作是否已完成:

public boolean isDone() {
    return done;
}

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

private volatile boolean done;

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

done = true;

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



 类似资料:
  • 如果我在main中这样做,它将创建一个新线程,并将向其提交一个任务以进行异步计算。 如果您看到FutureTask文档,它还会说: 可取消的异步计算。此类提供了Future的基本实现,包括启动和取消计算、查询计算是否完成以及检索计算结果的方法。 那么,FutureTask是如何进行异步计算的呢?它是否在内部创建线程,并提交我们在实例化FutureTask时给它的任务,比如: 否则它不可能是异步计算

  • 我编写了一个类,它的一系列实例将从AsyncTask调用,它将从方法runReport()返回一个结果。它很好地创建了一个工作线程,但由于某种原因,它不执行可调用的call()方法。我做错了什么? null 我愿意用更好的方法来做这件事。我最初让AsyncTask进行这个调用,然后在它的线程上运行looper.loop(),但是我无法处理这些对象的队列,因为我需要在返回结果之前从侦听器调用loop

  • 本文向大家介绍如何执行批量插入?相关面试题,主要包含被问及如何执行批量插入?时的应答技巧和注意事项,需要的朋友参考一下 首先,创建一个简单的 insert 语句:   然后在 java 代码中像下面这样执行批处理插入:

  • 问题内容: Hibernate不支持union,所以我想单独运行sql。但是最后如何合并这些值? 请告知如何分别执行两个sql,最后如何合并这些值? 问题答案: 请注意,UNION中的每个SELECT语句必须具有相同的列数。 这些列还必须具有相似的数据类型。另外,每个SELECT语句中的列必须具有相同的顺序。 如果是这样,请向您的查询添加别名: 您可以通过以下方式使用SQLQuery和AliasT

  • 问题内容: 我想使用hibernateHQL执行数据时间操作。 我想添加和减去两个日期,以及我想从特定日期减去1年或1个月。 在hibernate状态下如何使用HQL? 问题答案: 请参阅 在HQL中执行日期/时间数学运算? 举个例子 要使用自定义sql,您必须编写自己的hibernate方言并注册:

  • 问题内容: 发现在Java 1.6(以及从Eclipse)上运行时,吞没了该方法中的异常之后,我试图找到一种捕获这些异常的方法,而不会在我的所有实现中都添加throw / catch 。 该API建议覆盖应对此有所帮助: 导致此future报告一个ExecutionException,并以给定throwable作为其原因,除非已经设置或取消了此Future。计算失败时,run方法在内部调用此方法。