这个线程能不能存活以及如何使用java.lang.Thread.join()方法
Can this thread be alive and how to use java.lang.Thread.join() method
我之前阅读过一些 SO 问题和文档,但没有找到我的回复:
- How long a thread will be alive in java?
- When is a Java thread alive?
- http://journals.ecs.soton.ac.uk/java/tutorial/java/threads/states.html
所以...
public class MyThread extends Thread {
public MyThread() {
this.setName("MyThread-" + System.currentTimeMillis());
this.start();
}
public MyThread(long millis) throws InterruptedException {
this.setName("MyThread-" + System.currentTimeMillis());
this.join(millis);
this.start();
}
@Override
public void run() {
System.out.println("I am running...");
// This thread does not sleep... no Thread.sleep() in run method.
// Do some things like requesting a database
// Database response happens in less time that the timeout
}
}
public class MyClass {
public MyClass(){
for (int i = 0; i < 5; i++) {
Thread t1 = new MyThread();
t1.join(5000);
if (t1.isAlive()) {
System.out.println("I'm alive");
// do some things
} else {
System.out.println("I'm not alive");
}
Thread t2 = new MyThread(5000);
if (t2.isAlive()) {
System.out.println("I'm alive");
// do some things
} else {
System.out.println("I'm not alive");
}
}
}
}
似乎不可能,但是 t1
中的一个可能还活着吗? t2 呢?
当我在 start()
之后调用 join()
时发生了什么
有关信息,我正在使用:
- JVM:Java HotSpot(TM) 客户端 VM(20.45-b01,混合模式,共享)
- Java:版本 1.6。0_45,供应商 Sun Microsystems Inc.
阅读您的一些回复后更新
如果我理解的话,更好的实现应该是这样的:
public class MyThread extends Thread {
public MyThread() {
super("MyThread-" + System.currentTimeMillis());
}
@Override
public void run() {
System.out.println("I am running...");
// This thread does not sleep... no Thread.sleep() in run method.
// Do some things like requesting a database
// Database response happens in less time that the timeout
}
}
public class MyClass {
public MyClass(){
for (int i = 0; i < 5; i++) {
Thread t1 = new MyThread();
t1.start();
t1.join(5000);
if (t1.isAlive()) {
System.out.println("I'm alive");
// do some things
} else {
System.out.println("I'm not alive");
}
}
}
}
两个回复对我帮助很大: and
isAlive() 的文档说:
A thread is alive if it has been started and has not yet died.
join() 的文档说:
Waits at most millis milliseconds for this thread to die
所以,在 join() 之后 returns,
- 线程已经死亡,isAlive() 将为 false
- 或者线程还没有死但是延迟已经过去,isAlive() 可能为真。这是可能的,但可能性很小,因为线程有 5 秒的时间来完成打印到控制台的简单工作。
请注意,尽管 Thread.join(long)
的 (JDK 7) 文档说
Waits at most millis
milliseconds for this thread to die.
它还会继续
This implementation uses a loop of this.wait
calls conditioned on this.isAlive
.
并且Thread.isAlive
说:
A thread is alive if it has been started and has not yet died.
所以你的代码:
- 当调用
t1.isAlive()
时,它总是 false
因为你是在启动线程后加入的(从构造函数)。
- 调用
t2.isAlive()
时,大部分时间是true
因为
- 你在启动线程之前加入(在构造函数中),returns立即
- 线程刚刚启动(在构造函数中)
所以回答你的问题
It seems it can not be but could one of the t1
be alive ?
对于t1
,没有,只要你等待的时间超过运行。对于t2
,是.
你的t1.isAlive()
永远是假的。您正在执行的线程需要 运行 毫秒。您正在调用 t1.join(5000)
,它会在该线程死亡后 将该线程与当前线程连接起来 。因为它总是 运行s 快于 5 秒,所以当它到达你检查它是否还活着时它总是死了。
你的t2.isAlive()
永远是真的。在 t2 线程上,您在调用 start 方法之前在构造函数中调用 join 。由于线程始终处于死状态,直到调用构造函数中的 start 方法 returns 立即加入。然后允许调用 start 。即使在线程上调用 start 也不意味着它会立即执行。它只是将其标记为可执行,线程调度程序将在将来的某个时间启动它。由于您在构造函数之后立即调用 t2.isAlive()
,因此它将始终为真,因为当前线程还不会被换出。
使用您的代码,t1
个线程肯定会始终打印 "I'm not alive",以及 t2
、"I'm alive"。
对于 t2
线程,在启动线程之前调用 this.join(...)
很奇怪,因为(作为对@JB 指出的内容的补充),join()
doc 说
This implementation uses a loop of this.wait calls conditioned on this.isAlive.
并且,由于线程尚未启动,连接没有效果,returns立即。
但是你的问题是什么能让 t1
活着。只需在 run()
方法中添加一个 Thread.sleep(6000)
,您就会看到该线程处于活动状态。这意味着如果线程完成的任务(DB请求,...)比join()
中设置的超时时间长,那么答案是"yes, t1 can be alive"。
我之前阅读过一些 SO 问题和文档,但没有找到我的回复:
- How long a thread will be alive in java?
- When is a Java thread alive?
- http://journals.ecs.soton.ac.uk/java/tutorial/java/threads/states.html
所以...
public class MyThread extends Thread {
public MyThread() {
this.setName("MyThread-" + System.currentTimeMillis());
this.start();
}
public MyThread(long millis) throws InterruptedException {
this.setName("MyThread-" + System.currentTimeMillis());
this.join(millis);
this.start();
}
@Override
public void run() {
System.out.println("I am running...");
// This thread does not sleep... no Thread.sleep() in run method.
// Do some things like requesting a database
// Database response happens in less time that the timeout
}
}
public class MyClass {
public MyClass(){
for (int i = 0; i < 5; i++) {
Thread t1 = new MyThread();
t1.join(5000);
if (t1.isAlive()) {
System.out.println("I'm alive");
// do some things
} else {
System.out.println("I'm not alive");
}
Thread t2 = new MyThread(5000);
if (t2.isAlive()) {
System.out.println("I'm alive");
// do some things
} else {
System.out.println("I'm not alive");
}
}
}
}
似乎不可能,但是 t1
中的一个可能还活着吗? t2 呢?
当我在 start()
join()
时发生了什么
有关信息,我正在使用:
- JVM:Java HotSpot(TM) 客户端 VM(20.45-b01,混合模式,共享)
- Java:版本 1.6。0_45,供应商 Sun Microsystems Inc.
阅读您的一些回复后更新
如果我理解的话,更好的实现应该是这样的:
public class MyThread extends Thread {
public MyThread() {
super("MyThread-" + System.currentTimeMillis());
}
@Override
public void run() {
System.out.println("I am running...");
// This thread does not sleep... no Thread.sleep() in run method.
// Do some things like requesting a database
// Database response happens in less time that the timeout
}
}
public class MyClass {
public MyClass(){
for (int i = 0; i < 5; i++) {
Thread t1 = new MyThread();
t1.start();
t1.join(5000);
if (t1.isAlive()) {
System.out.println("I'm alive");
// do some things
} else {
System.out.println("I'm not alive");
}
}
}
}
两个回复对我帮助很大:
isAlive() 的文档说:
A thread is alive if it has been started and has not yet died.
join() 的文档说:
Waits at most millis milliseconds for this thread to die
所以,在 join() 之后 returns,
- 线程已经死亡,isAlive() 将为 false
- 或者线程还没有死但是延迟已经过去,isAlive() 可能为真。这是可能的,但可能性很小,因为线程有 5 秒的时间来完成打印到控制台的简单工作。
请注意,尽管 Thread.join(long)
的 (JDK 7) 文档说
Waits at most
millis
milliseconds for this thread to die.
它还会继续
This implementation uses a loop of
this.wait
calls conditioned onthis.isAlive
.
并且Thread.isAlive
说:
A thread is alive if it has been started and has not yet died.
所以你的代码:
- 当调用
t1.isAlive()
时,它总是false
因为你是在启动线程后加入的(从构造函数)。 - 调用
t2.isAlive()
时,大部分时间是true
因为- 你在启动线程之前加入(在构造函数中),returns立即
- 线程刚刚启动(在构造函数中)
所以回答你的问题
It seems it can not be but could one of the
t1
be alive ?
对于t1
,没有,只要你等待的时间超过运行。对于t2
,是.
你的t1.isAlive()
永远是假的。您正在执行的线程需要 运行 毫秒。您正在调用 t1.join(5000)
,它会在该线程死亡后 将该线程与当前线程连接起来 。因为它总是 运行s 快于 5 秒,所以当它到达你检查它是否还活着时它总是死了。
你的t2.isAlive()
永远是真的。在 t2 线程上,您在调用 start 方法之前在构造函数中调用 join 。由于线程始终处于死状态,直到调用构造函数中的 start 方法 returns 立即加入。然后允许调用 start 。即使在线程上调用 start 也不意味着它会立即执行。它只是将其标记为可执行,线程调度程序将在将来的某个时间启动它。由于您在构造函数之后立即调用 t2.isAlive()
,因此它将始终为真,因为当前线程还不会被换出。
使用您的代码,t1
个线程肯定会始终打印 "I'm not alive",以及 t2
、"I'm alive"。
对于 t2
线程,在启动线程之前调用 this.join(...)
很奇怪,因为(作为对@JB 指出的内容的补充),join()
doc 说
This implementation uses a loop of this.wait calls conditioned on this.isAlive.
并且,由于线程尚未启动,连接没有效果,returns立即。
但是你的问题是什么能让 t1
活着。只需在 run()
方法中添加一个 Thread.sleep(6000)
,您就会看到该线程处于活动状态。这意味着如果线程完成的任务(DB请求,...)比join()
中设置的超时时间长,那么答案是"yes, t1 can be alive"。