gpt4 book ai didi

java - 线程怎么可能已经启动了?

转载 作者:行者123 更新时间:2023-12-02 05:55:26 27 4
gpt4 key购买 nike

我有一个单实例线程类。

public class LogThread extends Thread{

private static LogThread instance = null;
private volatile boolean isRunning = false;
private final static Object instanceLock = new Object();

public static synchronized LogThread getInstance(){
synchronized(instanceLock){
if(instance == null)
instance = new LogThread();
}
return instance;
}

@Override
public run(){
//Doing some run stuff
//Once run is finished

synchronized(instanceLock){
isRunning = false;
instance = null;
}
}

@Override
public synchronized void start() {
synchronized (instanceLock){
if(!isRunning){
isRunning = true;
super.start();
}
}
}
}

每次获取实例时,我都会从另一个线程调用 start,并且每隔一段时间我就会在 com.......LogThread.start,第 x 行线程已启动中收到 IllegalThreadStateException。

如果我在启动线程之前设置了isRunning并基于instanceLock同步它,线程怎么可能已经启动了。

编辑::我已将 getInstance() 编辑为以下内容:

 public static synchronized LogThread getInstance(){
synchronized(instanceLock){
if(instance == null){
instance = new LogThread();
instance.start();
}
}
}

它应该停止任何启动已启动线程的尝试。

最佳答案

顺序是这样的:

  • 线程 A 调用 getInstance。线程 A 获取锁一段时间,是时候检查 instance 是否不为 null,而此时它不为 null。
  • Thread LogThread 完成执行,isRunning 设置为 false。 instance 设置为 false,但仍被线程 A 保留
  • 线程 A 在实例上调用 startisRunning 为 false,因此调用 start,从而导致崩溃。

一个快速修复方法是不将 isRunning 设置为 false,因为该实例没有任何充分的理由可用于重新启动。然后应将其重命名为 isStarted 以与其功能保持一致。

正确的解决方案是使用 newSingleThreadExecutor,如 @Mani 所建议

关于java - 线程怎么可能已经启动了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23138356/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com