线程无法启动吗?

时间:2016-12-13 01:14:18

标签: java multithreading

我想从不同的线程运行一些代码,并在一段时间后让它超时。我还希望能够定期运行一些其他代码(即刷新一些输出或其他东西)。

这基本上就是我的做法:

Thread operation = new Thread() { ... };
operation.start();

// Check if Thread is still alive every 100ms
for (int i = 0; i < timeout / 100; i++) {
    somethingToDoWhileWaiting(...);
    if (!operation.isAlive()) {
        break; // Thread is dead so we can end early
    }
    Thread.sleep(100);
}

if (operation.isAlive()) {
    operation.interrupt(); // timed out
}

我的问题是,是否存在线程无法启动的任何方式(没有抛出某种异常),或者当我想检查它还活着时它可能还没有开始?

如同,有机会:

  1. 我致电operation.start()并且不会引发任何错误。

  2. 我进入循环并检查它是否还活着

  3. 不是(因为它还没有开始或者出现幕后错误)?

  4. 除此之外,是否有更好的方法来检查线程是否已经结束(或者它已经正确启动了 - 我想到循环直到它还活着,但我对此有同样的担心)?

3 个答案:

答案 0 :(得分:4)

这是使用ExecutorService和Futures的好地方:

Runnable task = new Runnable() { ... };
ExecutorService executor = Executors.newFixedThreadPool(1);
Future<Void> future = executor.submit(task);

// Check if Thread is still alive every 100ms
for (int i = 0; i < timeout / 100; i++) {
    somethingToDoWhileWaiting(...);
    if (!future.isDone()) {
        break; // Thread is dead so we can end early
    }
    Thread.sleep(100);
}

if (!future.isDone()) {
    future.cancel(true);
}

关于你的核心问题:线程受操作系统调度程序的支配。线程可以永远不会启动;但是,这非常不可能,因为OS调度程序非常擅长它的工作。如果在没有线程工作的情况下花费了相当多的时间,那么您的代码更有可能存在错误。

答案 1 :(得分:2)

ExecutorsFutures是其他人指出的方式。

但要专门回答你的问题

  

是否有任何方式线程无法启动(没有抛出某种异常),或者在我想检查它还活着的时候它可能没有启动?

回答:线程将启动或抛出异常。周期。

查看Thread.start()方法的文档here

除此之外,这是start方法的代码。你可以通过它来感受它。

public synchronized void start() {
    /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
     */
    if (threadStatus != 0)
        throw new IllegalThreadStateException();

    /* Notify the group that this thread is about to be started
     * so that it can be added to the group's list of threads
     * and the group's unstarted count can be decremented. */
    group.add(this);

    boolean started = false;
    try {
        start0();
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
            /* do nothing. If start0 threw a Throwable then
              it will be passed up the call stack */
        }
    }
}

private native void start0();

希望这有帮助。

答案 2 :(得分:-2)

使用Thread.join() - 它将一直阻塞,直到Thread退出。