我有一个简单的(或者至少我认为是)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/