Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/382.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Thread.start()在Thread.isAlive()检查后引发异常_Java_Multithreading - Fatal编程技术网

Java Thread.start()在Thread.isAlive()检查后引发异常

Java Thread.start()在Thread.isAlive()检查后引发异常,java,multithreading,Java,Multithreading,我正在学习Java中的多线程,遇到了一个奇怪的问题 当我尝试使用thread.start()与我的调度程序启动一个新线程时,我了解到我们需要一个thread.isAlive()检查,因为启动和恢复需要不同的进程。但是,此代码显示检查和start(): 其中current保证为有效线程。我最后犯了这个错误 Exception in thread "Thread-0" java.lang.IllegalThreadStateException at java.base/java.la

我正在学习Java中的多线程,遇到了一个奇怪的问题

当我尝试使用
thread.start()
与我的调度程序启动一个新线程时,我了解到我们需要一个
thread.isAlive()
检查,因为启动和恢复需要不同的进程。但是,此代码显示检查和
start()

其中current保证为有效线程。我最后犯了这个错误

Exception in thread "Thread-0" java.lang.IllegalThreadStateException
        at java.base/java.lang.Thread.start(Thread.java:790)
        at Scheduler.run(Scheduler.java:152)
这就是为什么我认为在不应该调用时调用
start()
是个问题。但是,在所有情况下,它不应该调用
start()
,除非线程处于非活动状态

因此,我的问题有两个方面:

  • 如果线程已经启动,上面的代码是否存在允许第二个块运行的错误,以及

  • 还有什么事情会出错,从而引发异常?我在
    setDaemon()
    中看到了相同的异常,但是我没有调用它,因此这应该是无关的


  • 您的方法的问题是无法“重用”
    Thread
    实例,因此不能对
    Thread
    的同一实例多次调用
    start
    方法。从文档:

    测试此线程是否处于活动状态如果线程已启动但尚未终止,则该线程处于活动状态。

    因此,如果
    线程
    已启动且已死亡(以及尚未启动时),则可能会陷入
    else
    状态。如果您再次尝试启动它,您将得到一个异常,因为如果您尝试启动它,会抛出
    IllegalThreadStateException
    。从以下文件:

    多次启动线程是不合法的。特别是,线程一旦完成执行,就不能重新启动

    抛出:
    非法线程状态异常
    -如果线程已启动

    如果要暂停/恢复线程,可以以正确的方式使用
    wait
    /
    notifyAll
    ——请参阅。

    a有一个,可通过调用来检索。
    状态的javadoc显示:

    线程状态。线程可以处于以下状态之一:

    • 新建

      尚未启动的线程处于此状态
    • RUNNABLE

      在Java虚拟机中执行的线程处于此状态
    • 被阻止

      等待监视器锁定而被阻止的线程处于此状态
    • 等待

      无限期等待另一个线程执行特定操作的线程处于此状态
    • 定时等待

      等待另一个线程执行操作达指定等待时间的线程处于此状态
    • 终止

      已退出的线程处于此状态
    线程在给定时间点只能处于一种状态。这些状态是虚拟机状态,不反映任何操作系统线程状态

    当您调用时,线程将离开
    NEW
    状态,并且将不再具有该状态。
    start()的Javadoc说:

    如果线程已启动,则抛出非法线程状态异常

    这意味着如果状态不是新的

    然而,该公司的javadoc表示:

    测试此线程是否处于活动状态。如果线程已启动但尚未死亡,则该线程是活动的

    这意味着线程不是新的(已启动)线程,也不是终止的(尚未终止)

    正如您所看到的,
    isAlive()
    将为
    TERMINATED
    返回false,即使
    TERMINATED
    不是启动线程的有效状态

    如果需要知道是否可以启动线程,请检查状态:

    if (thread.getState() == Thread.State.NEW) {
        thread.start();
        // Ok, the thread is now beginning to work on it
    } else if (thread.getState() != Thread.State.TERMINATED) {
        // Yay, the thread is working on it
    } else {
        // Oops, what happened???
    ]
    

    你学错了
    isAlive()
    告诉您它是否已经启动,还没有完成。它不会告诉您是否可以调用
    start()
    。您不能重用
    Thread
    对象,特别是不能对它们调用两次
    start()
    。方法“抛出:IllegalThreadStateException-如果线程已经启动。”并且您只能调用
    setPriority(4)如果线程尚未启动。
    
    if (thread.getState() == Thread.State.NEW) {
        thread.start();
        // Ok, the thread is now beginning to work on it
    } else if (thread.getState() != Thread.State.TERMINATED) {
        // Yay, the thread is working on it
    } else {
        // Oops, what happened???
    ]