Как в Java определить, запущен ли поток?

Ответы:

93

Thread.isAlive()

Уэйн
источник
Я предполагаю, что он имеет некоторое отличие от Thread.State.RUNNABLE(последний кажется более надежным)
user924 09
33

Вы можете использовать этот метод:

boolean isAlive()

Он возвращает true, если поток все еще жив, и false, если поток мертв. Это не статично. Вам нужна ссылка на объект класса Thread.

Еще один совет: если вы проверяете его статус, чтобы заставить основной поток ждать, пока новый поток все еще работает, вы можете использовать метод join (). Так удобнее.

Абдулсаттар Мохаммед
источник
20

Я думаю, вы можете использовать GetState () ; Он может возвращать точное состояние потока.

Чатуранга Чандрасекара
источник
9

Проверьте статус потока, позвонив Thread.isAlive.

что-то
источник
6

Точнее,

Thread.isAlive() возвращает истину, если поток был запущен (возможно, еще не запущен), но еще не завершил свой метод выполнения.

Thread.getState() возвращает точное состояние потока.

sxnamit
источник
5

Класс перечисления Thread.State и новый API getState () предоставляются для запроса состояния выполнения потока.

В определенный момент времени поток может находиться только в одном состоянии. Эти состояния представляют собой состояния виртуальной машины, которые не отражают состояния потоков операционной системы [ NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED].

enum Thread.State extends Enum реализует Serializable , Comparable

  • getState ()jdk5 - public State getState() {...} « Возвращает состояние thisпотока. Этот метод предназначен для использования при мониторинге состояния системы, а не для управления синхронизацией.

  • isAlive () - public final native boolean isAlive(); « Возвращает истину, если поток, из которого он вызывается, все еще жив, иначе возвращает ложь . Поток жив, если он был запущен и еще не умер.

Примеры исходного кода классов 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();
        }
    }
}

@Смотрите также

Яш
источник
A thread is alive if it has been started and has not yet died. Что значит умер? Состояние есть TERMINATED?
KunLun 04
2

Попросите ваш поток уведомить другой поток о завершении. Таким образом, вы всегда будете точно знать, что происходит.

Бомба
источник
1

Задумавшись написать код для демонстрации методов 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'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());
    }


}
Рошан
источник
1

Вы можете использовать: Thread.currentThread().isAlive();. Возвращает истину, если этот поток жив; иначе ложь .

Су
источник
Разве это не всегда будет верным? Я думаю, это должен быть дескриптор другого потока. В конце концов, разве текущий поток не будет выполняться, Thread.currentThread().isAlive()поэтому всегда будет возвращать истину?
Мэтью
1

Используйте Thread.currentThread (). IsAlive (), чтобы проверить, жив ли поток [вывод должен быть истинным], что означает, что поток все еще выполняет код внутри метода run () или используйте метод Thread.currentThread.getState (), чтобы получить точное состояние резьбы.

Хасинду Даханаяке
источник