W jaki sposób w Javie można określić, czy wątek jest uruchomiony?

84

Jak ustalić, czy wątek jest uruchomiony?

tshepang
źródło

Odpowiedzi:

93

Thread.isAlive()

Wayne
źródło
Myślę, że ma pewną różnicę od Thread.State.RUNNABLE(ostatni wydaje się bardziej niezawodny)
user924
33

Możesz użyć tej metody:

boolean isAlive()

Zwraca wartość true, jeśli wątek nadal żyje, a false, jeśli wątek jest martwy. To nie jest statyczne. Potrzebujesz odwołania do obiektu klasy Thread.

Jeszcze jedna wskazówka: jeśli sprawdzasz jego status, aby główny wątek czekał, podczas gdy nowy wątek nadal działa, możesz użyć metody join (). Jest bardziej poręczny.

Abdulsattar Mohammed
źródło
20

Myślę, że możesz użyć GetState () ; Może zwrócić dokładny stan wątku.

Chathuranga Chandrasekara
źródło
9

Sprawdź stan wątku, dzwoniąc Thread.isAlive.

sth
źródło
6

Być precyzyjnym,

Thread.isAlive() zwraca wartość true, jeśli wątek został uruchomiony (może jeszcze nie być uruchomiony), ale nie zakończył jeszcze swojej metody uruchamiania.

Thread.getState() zwraca dokładny stan wątku.

sxnamit
źródło
5

Klasa Thread.State enum i nowy interfejs API getState () służą do wysyłania zapytań o stan wykonania wątku.

Wątek może znajdować się tylko w jednym stanie w danym momencie. Te stany to stany maszyny wirtualnej, które nie odzwierciedlają żadnych stanów wątków systemu operacyjnego [ NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED].

enum Thread.State rozszerza Enum implementuje Serializable , Comparable

  • getState ()jdk5 - public State getState() {...} « Zwraca stan thiswątku. Ta metoda jest przeznaczona do monitorowania stanu systemu, a nie do sterowania synchronizacją.

  • isAlive () - public final native boolean isAlive(); « Zwraca wartość true, jeśli wątek, na którym jest wywoływany, nadal żyje, w przeciwnym razie zwraca wartość false . Wątek żyje, jeśli został uruchomiony i jeszcze nie umarł.

Przykładowe kody źródłowe klas java.lang.Threadi 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;
        }
    }
}

Przykład z java.util.concurrent.CountDownLatchwykonywaniem wielu wątków równolegle, po wykonaniu wszystkich wątków główny wątek. (dopóki równoległe wątki nie ukończą zadania, główny wątek zostanie zablokowany).

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();
        }
    }
}

@Zobacz też

Yash
źródło
A thread is alive if it has been started and has not yet died. Co znaczy umarł? Stan jest TERMINATED?
KunLun
2

Niech twój wątek powiadomi inny wątek, kiedy się skończy. W ten sposób zawsze będziesz dokładnie wiedzieć, co się dzieje.

Bombe
źródło
1

Pomyślano napisać kod demonstrujący metody isAlive (), getState () , w tym przykładzie monitoruje wątek, który nadal się kończy (umiera).

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());
    }


}
Roshan
źródło
1

Można użyć: Thread.currentThread().isAlive();. Zwraca wartość true, jeśli ten wątek żyje; w przeciwnym razie fałsz .

Su
źródło
1

Użyj Thread.currentThread (). IsAlive (), aby sprawdzić, czy wątek żyje [dane wyjściowe powinny być prawdziwe], co oznacza, że ​​wątek nadal wykonuje kod wewnątrz metody run () lub użyj metody Thread.currentThread.getState () , aby uzyskać dokładny stan wątku.

Hasindu Dahanayake
źródło