In Java, how do you determine if a thread is running?

后端 未结 10 2185
-上瘾入骨i
-上瘾入骨i 2020-11-28 11:30

How do you determine if a thread is running?

相关标签:
10条回答
  • 2020-11-28 12:16

    You can use this method:

    boolean isAlive()
    

    It returns true if the thread is still alive and false if the Thread is dead. This is not static. You need a reference to the object of the Thread class.

    One more tip: If you're checking it's status to make the main thread wait while the new thread is still running, you may use join() method. It is more handy.

    0 讨论(0)
  • 2020-11-28 12:16

    Use Thread.currentThread().isAlive() to see if the thread is alive[output should be true] which means thread is still running the code inside the run() method or use Thread.currentThread.getState() method to get the exact state of the thread.

    0 讨论(0)
  • 2020-11-28 12:21

    Thread.State enum class and the new getState() API are provided for querying the execution state of a thread.

    A thread can be in only one state at a given point in time. These states are virtual machine states which do not reflect any operating system thread states [NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, TERMINATED].

    enum Thread.State extends Enum implements Serializable, Comparable

    • getState()jdk5 - public State getState() {...} « Returns the state of this thread. This method is designed for use in monitoring of the system state, not for synchronization control.

    • isAlive() - public final native boolean isAlive(); « Returns true if the thread upon which it is called is still alive, otherwise it returns false. A thread is alive if it has been started and has not yet died.

    Sample Source Code's of classes java.lang.Thread and 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;
            }
        }
    }
    

    Example with java.util.concurrent.CountDownLatch to execute multiple threads parallel, After completing all threads main thread execute. (until parallel threads complete their task main thread will be blocked.)

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

    @See also

    • “implements Runnable” vs. “extends Thread”
    • Thread States
    • Thread States Diagram
    • How to start two threads at “exactly” the same time
    0 讨论(0)
  • 2020-11-28 12:25

    Thought to write a code to demonstrate the isAlive() , getState() methods, this example monitors a thread still it terminates(dies).

    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());
        }
    
    
    }
    
    0 讨论(0)
提交回复
热议问题