Ответ 1
Thread.isAlive()
Как вы определяете, работает ли поток?
Thread.isAlive()
Вы можете использовать этот метод:
boolean isAlive()
Он возвращает true, если поток все еще жив и false, если поток мертв. Это не статично. Вам нужна ссылка на объект класса Thread.
Еще один совет: Если вы проверяете статус, чтобы ожидание основного потока продолжалось, пока новый поток все еще запущен, вы можете использовать метод join(). Это более удобно.
Я думаю, вы можете использовать GetState(); Он может вернуть точное состояние потока.
Проверьте статус потока, вызвав Thread.isAlive
.
Если быть точным,
Thread.isAlive()
возвращает true, если поток был запущен (возможно, еще не запущен), но еще не завершил свой метод выполнения.
Thread.getState()
возвращает точное состояние потока.
Класс enum Thread.State и новый API getState() предназначены для запроса состояния выполнения потока.
Поток может находиться только в одном состоянии в данный момент времени. Эти состояния являются состояниями виртуальной машины, которые не отражают состояния потоков операционной системы [ NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED
].
enum Thread.State расширяет Enum реализует Serializable, Comparable
getState() jdk5
- public State getState() {...}
" Возвращает состояние this
потока. Этот метод предназначен для использования в мониторинге состояния системы, а не для контроля синхронизации.
isAlive() - public final native boolean isAlive();
" Возвращает true, если поток, для которого он вызван, еще жив, в противном случае он возвращает false. Поток жив, если он был запущен и еще не умер.
Пример исходного кода классов java.lang.Thread
и sun.misc.VM
package java.lang;
public class Thread implements Runnable {
public final native boolean isAlive();
// Java thread status value zero corresponds to state "NEW" - 'not yet started'.
private volatile int threadStatus = 0;
public enum State {
NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED;
}
public State getState() {
return sun.misc.VM.toThreadState(threadStatus);
}
}
package sun.misc;
public class VM {
// ...
public static Thread.State toThreadState(int threadStatus) {
if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
return Thread.State.RUNNABLE;
} else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
return Thread.State.BLOCKED;
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {
return Thread.State.WAITING;
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {
return Thread.State.TIMED_WAITING;
} else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {
return Thread.State.TERMINATED;
} else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {
return Thread.State.NEW;
} else {
return Thread.State.RUNNABLE;
}
}
}
Пример с java.util.concurrent.CountDownLatch
для параллельного выполнения нескольких потоков. После завершения всех потоков выполняется основной поток. (пока параллельные потоки не завершат свою задачу, основной поток будет заблокирован.)
public class MainThread_Wait_TillWorkerThreadsComplete {
public static void main(String[] args) throws InterruptedException {
System.out.println("Main Thread Started...");
// countDown() should be called 4 time to make count 0. So, that await() will release the blocking threads.
int latchGroupCount = 4;
CountDownLatch latch = new CountDownLatch(latchGroupCount);
new Thread(new Task(2, latch), "T1").start();
new Thread(new Task(7, latch), "T2").start();
new Thread(new Task(5, latch), "T3").start();
new Thread(new Task(4, latch), "T4").start();
//latch.countDown(); // Decrements the count of the latch group.
// await() method block until the current count reaches to zero
latch.await(); // block until latchGroupCount is 0
System.out.println("Main Thread completed.");
}
}
class Task extends Thread {
CountDownLatch latch;
int iterations = 10;
public Task(int iterations, CountDownLatch latch) {
this.iterations = iterations;
this.latch = latch;
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
System.out.println(threadName + " : Started Task...");
for (int i = 0; i < iterations; i++) {
System.out.println(threadName + " : "+ i);
sleep(1);
}
System.out.println(threadName + " : Completed Task");
latch.countDown(); // Decrements the count of the latch,
}
public void sleep(int sec) {
try {
Thread.sleep(1000 * sec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Смотрите также
Попросите свой поток сообщить какой-либо другой поток, когда он закончил. Таким образом, вы всегда точно знаете, что происходит.
Мысль написать код для демонстрации методов isAlive(), getState(), этот пример контролирует поток, который все еще завершается (умирает).
package Threads;
import java.util.concurrent.TimeUnit;
public class ThreadRunning {
static class MyRunnable implements Runnable {
private void method1() {
for(int i=0;i<3;i++){
try{
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedException ex){}
method2();
}
System.out.println("Existing Method1");
}
private void method2() {
for(int i=0;i<2;i++){
try{
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedException ex){}
method3();
}
System.out.println("Existing Method2");
}
private void method3() {
for(int i=0;i<1;i++){
try{
TimeUnit.SECONDS.sleep(1);
}catch(InterruptedException ex){}
}
System.out.println("Existing Method3");
}
public void run(){
method1();
}
}
public static void main(String[] args) {
MyRunnable runMe=new MyRunnable();
Thread aThread=new Thread(runMe,"Thread A");
aThread.start();
monitorThread(aThread);
}
public static void monitorThread(Thread monitorMe) {
while(monitorMe.isAlive())
{
try{
StackTraceElement[] threadStacktrace=monitorMe.getStackTrace();
System.out.println(monitorMe.getName() +" is Alive and it state ="+monitorMe.getState()+" || Execution is in method : ("+threadStacktrace[0].getClassName()+"::"+threadStacktrace[0].getMethodName()+") @line"+threadStacktrace[0].getLineNumber());
TimeUnit.MILLISECONDS.sleep(700);
}catch(Exception ex){}
/* since threadStacktrace may be empty upon reference since Thread A may be terminated after the monitorMe.getStackTrace(); call*/
}
System.out.println(monitorMe.getName()+" is dead and its state ="+monitorMe.getState());
}
}