Come si determina se un thread è in esecuzione?
Risposte:
Puoi usare questo metodo:
boolean isAlive()
Restituisce true se il thread è ancora attivo e false se il thread è morto. Questo non è statico. Hai bisogno di un riferimento all'oggetto della classe Thread.
Un altro consiglio: se stai controllando il suo stato per far aspettare il thread principale mentre il nuovo thread è ancora in esecuzione, puoi usare il metodo join (). È più utile.
Penso che tu possa usare GetState () ; Può restituire lo stato esatto di un thread.
La classe enum Thread.State e la nuova API getState () vengono fornite per interrogare lo stato di esecuzione di un thread.
Un thread può trovarsi in un solo stato in un determinato momento. Questi stati sono stati della macchina virtuale che non riflettono alcuno stato del thread del sistema operativo [ NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED
].
enum Thread.State estende Enum implementa Serializable , Comparable
getState ()jdk5
- public State getState() {...}
« Restituisce lo stato del this
thread. Questo metodo è progettato per essere utilizzato nel monitoraggio dello stato del sistema, non per il controllo della sincronizzazione.
isAlive () - public final native boolean isAlive();
« Restituisce true se il thread su cui è stato chiamato è ancora attivo, altrimenti restituisce false . Un thread è vivo se è stato avviato e non è ancora morto.
Esempio di codice sorgente di classi java.lang.Thread
e 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;
}
}
}
Esempio con java.util.concurrent.CountDownLatch
per eseguire più thread in parallelo, Dopo aver completato tutti i thread eseguire il thread principale. (finché i thread paralleli non completano l'attività, il thread principale verrà bloccato.)
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();
}
}
}
@Guarda anche
A thread is alive if it has been started and has not yet died
. Cosa significa morto? Lo stato è TERMINATED
?
Pensato di scrivere un codice per dimostrare i metodi isAlive (), getState () , questo esempio monitora un thread che tuttavia termina (muore).
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's 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());
}
}
È possibile utilizzare: Thread.currentThread().isAlive();
. Restituisce vero se questo thread è attivo; altrimenti falso .
Thread.currentThread().isAlive()
quindi restituendo sempre true?
Usa Thread.currentThread (). IsAlive () per vedere se il thread è vivo [l'output dovrebbe essere vero] il che significa che il thread sta ancora eseguendo il codice all'interno del metodo run () o usa il metodo Thread.currentThread.getState () per ottenere il stato esatto del thread.
Thread.State.RUNNABLE
(l'ultimo sembra più affidabile)