Java 线程未启动(或需要很长时间才能启动)

标签 java multithreading spring-boot

我有一个简单的(或者至少我认为是)Java 应用程序,它在线程中执行一些工作。

类似于:

public class Task implements Runnable {

    public boolean running = false;

    public void run() {
        running = true;
        // long running processing
    }
}

...

void startTask() {
    Task task = new Task();
    Thread thread = new Thread(task);
    thread.start();
    // I added this thinking the calling thread might terminate before
    // the new thread starts
    while (!task.running) {
        try {
            Thread.sleep(1);
        } catch (InterruptedException ie) {
            // log error
    }
}
调用上面的

startTask() 以响应 REST 请求(这是一个 Spring Boot 应用程序)。它在我的开发机器(Windows 10、Oracle JDK)和 Amazon EC2 实例(Amazon Linux、OpenJDK)上运行良好,但在 Google Compute 实例(Ubuntu 16.04、OpenJDK)上运行不佳。在后一种情况下,工作线程要么永远不会启动(task.running 永远不会设置为 true),要么有时会在 60 多秒后启动。我很困惑。

鉴于任务本身不是很复杂(加上设置“运行”标志是它做的第一件事,而这从来没有发生过)让我认为这是一些奇怪的 JVM/系统相关问题,但是我真的不知道。

最令人沮丧的是它有时 有效(通常是我在重建后第一次上传/运行它时)。并且从未在我的 PC 上运行失败。

编辑:我曾尝试在 Ubuntu 中使用 Oracle JRE,但同样没有成功。

第二次编辑:是的,我在此处编写示例代码时犯了一些错误。固定。

最佳答案

Runnable 是一个接口(interface),因此您正在创建一个名为 Task 的新接口(interface)!但是,您还提供了 run() 方法的实现。这不会编译。

可能,这就是你想要做的:

class Task implements Runnable {
    public boolean running = false;

    @Override
    public void run() {
        running = true;
        // long running processing
    }
}

另一个错误是你直接调用了线程的run()方法! 您应该改为调用 start()。

示例代码可能如下所示:

void startTask() {
    Task task = new Task();
    Thread thread = new Thread(task);
    thread.start();
    // I added this thinking the calling thread might terminate before
    // the new thread starts
    while (!task.running) {
        try {
            Thread.sleep(1);
        } 
        catch (InterruptedException ie) {
            // log error
        }
    }
} 

关于Java 线程未启动(或需要很长时间才能启动),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42897794/

相关文章:

java - SpringBoot @RequestBody 抽象类验证

c# - 当我没有可用的控件时如何调用()

java - 在单个 Activity 中使用两个 ScrollView 的正确方法是什么?

java - Tomcat Java Servlet - 在应用程序启动时初始化类

java - 从android中的蓝牙设备读取数据

java - Java 中 Atomic set() 和 getAndSet() 方法的区别

java - sleep 和等待线程消耗多少资源

java - 使用 Collection 框架计算值(value)的百分比

java - LocalSessionFactoryBean 类型已弃用

java - Android:从 "Downloads"文件夹中删除下载的文件快捷方式