编程知识 cdmana.com

Java thread state and switch

Java Thread state and switch

One 、 What is? Java Thread state

stay Java In the program , Used to describe Java Six states of thread :

  • newly build (NEW): Current thread , It's just been built , Not yet started .
  • function (RUNNABLE): Current thread , In competition CPU Time sliced or acquired CPU The state of the time slice .
  • wait for (WAITTING): Current thread , In dormancy , No participation CPU The state of time slice competition .
  • Wait regularly (TIMED_WAITTING): Current thread , In a timed sleep , Don't take part in CPU The state of time slice competition .
  • Blocking (BLOCKED): Current thread , It's in a jam , No participation CPU The state of time slice competition .
  • End (TERMINATED): Current thread , In a state of final cessation .

New state , Can only enter the running state . The termination state cannot be changed to any other state .

wait for / Timed waiting and blocking , The difference is that the latter requires an event signal ( If other threads abandon the exclusive lock required by the current thread ), Before you can switch state . Of course , It's OK to force closure .

Java Thread implementation is not subject to JVM Normative constraints , So the implementation of different virtual machines , It's often different . At present, the mainstream HotSpot It's going to be every Java Threads are mapped directly to native threads of an operating system , Thus, the operating system completes a series of thread scheduling

Two 、 Where to see Java Thread state

see Java Thread state , There are three main ways :

  • java.lang.Thread.State You can directly see Java Six thread states of
  • Java Runtime , Inside the program, you can use Thread.getState() Get target thread status
  • Java Runtime , Outside the program, you can use jstack Tools such as , View thread status

of jstack Wait for tools to use , There will be blogs later , To elaborate on .

3、 ... and 、 When to change Java Thread state

Java Thread state switching . No verbosity , Directly above .
 Insert picture description here
This picture covers Java Various methods of thread state switching . Compared with some pictures on the Internet , More detailed .
If something is missing , Can tell me , I'll fill it in time .

Four 、 Who is using Java Thread state

Daily development , We don't interact directly with thread state .
We often use JDK Packaged tools , Such as JUC All kinds of tools under the bag .

Take a chestnut

Application in thread pool

Location :com.sun.corba.se.impl.orbutil.threadpool.ThreadPoolImpl#close


    // Note that this method should not return until AFTER all threads have died.
    public void close() throws IOException {

        // Copy to avoid concurrent modification problems.
        List<WorkerThread> copy = null;
        synchronized (workersLock) {
            copy = new ArrayList<>(workers);
        }

        for (WorkerThread wt : copy) {
            wt.close();
            while (wt.getState() != Thread.State.TERMINATED) {
                try {
                    wt.join();
                } catch (InterruptedException exc) {
                    wrapper.interruptedJoinCallWhileClosingThreadPool(exc, wt, this);
                }
            }
        }

        threadGroup = null;
    }

Actually check JDK After the discovery ,JDK In fact, there are not so many examples of spicy , And most of them are directly related to the thread state , It's also something about status checking .
This is said at the beginning of the article ,Java Thread operation , It's very low-level , Even the implementation is not included in the virtual machine specification .
Mainstream HotSpot, It's also a direct way to Java Threads map to system threads , By the system to carry out a series of thread scheduling processing .
therefore , stay JDK in , There is little direct processing of the state of the thread .

5、 ... and 、 Why thread state is needed

1. Why the concept of thread state is needed

This problem , It can be explained from two aspects : Life cycle and resource management

  • One side , Thread state is a good description of the whole life cycle of a thread , The different stages in the life cycle are divided effectively .
  • On the other hand , Resources are limited , The demand is infinite . So we need to schedule the system resources consciously , Make rational use of comparative advantages , The pursuit of Pareto optimality .

Realize the latter , It is the use of thread in the different stages of the life cycle of this natural attribute of the description of state , The grouping that was carried out .CPU Scheduling only needs to focus on the running state of the thread . And jam , Wait for threads , They all have their own way of handling . Finally get the resources ( Development response to complexity , The runtime consumes system resources , The growth of the user's mental model, etc ) The optimal allocation of .

2.JDK Why do we need to define Java Thread state

I said before ,Java Thread state is rarely used directly in . So why are you still in JDK In the definition of Java The six thread states of ?
One side , Through information transparency , Reduce the cost of building mental models for users . Such as , Now we can print logs , Breaking point , Quickly understand Java State of each thread of , And have a clear understanding of the causes . This greatly improves our understanding of Java Understanding of threads , And embrace more happily JUC Package, such as thread pool and other tools .
On the other hand , By enumerating states that can be applied directly , We can make a good secondary development of the existing tools . For example, we can expand AQS, And add the verification of thread state in it , So we can get a customized thread synchronization tool .

6、 ... and 、 How to use thread state

How to use it , I've already said that : Study Java Threads , Custom thread related tool development .
Here is an example of thread learning demo:


/**
 * @program: learning
 * @description:  Used to confirm thread status problems 
 * @author: Jarry
 * @create: 2020-10-26 22:25
 **/
public class ThreadState {

    public static void main(String[] args) {
        threadStateTest();
//        threadStateTest2();
//        threadStateWithBlocked();
//        threadStateWithException();
//        threadStateWithSuspend();
    }

    /**
     *  Practice has proved :Thread.suspend() And Thread.resume() Does not change the thread state 
     *  The thread state should be Waiting, Just Waiting. The Timed_Waiting Just Timed_Waiting
     * Thread.suspend() And Thread.resume() Just suspend the target thread ( And does not release lock resources )
     */
    private static void threadStateWithSuspend() {
        Thread thread1 = new Thread(() -> {
//            LockSupport.park();
            LockSupport.parkNanos(2000000000);
        });

        thread1.start();
        printThreadState(thread1);
        LockSupport.parkNanos(500000000);
        printThreadState(thread1);
        thread1.suspend();
        printThreadState(thread1);
        LockSupport.parkNanos(500000000);
        printThreadState(thread1);
        thread1.resume();
        LockSupport.parkNanos(500000000);
        printThreadState(thread1);

//        LockSupport.unpark(thread1);
    }

    /**
     *  Show thread blocking status 
     */
    private static void threadStateWithBlocked() {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                synchronized (ThreadState.class) {
//                    LockSupport.parkNanos(2000000000);
                    LockSupport.park();
                }
            }
        };

        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);

        thread1.start();
        LockSupport.parkNanos(500000000);
        thread2.start();
        //  Add the following intervals , Then the result :Runnable->Blocked
        //  inference :Thread.start() The thread state is set to Runnable, And then I met sync Lock of , Then switch to Blocked state 
//        LockSupport.parkNanos(500000000);

        printThreadState(thread2);
        LockSupport.parkNanos(500000000);
        printThreadState(thread2);

        LockSupport.parkNanos(500000000);
        LockSupport.unpark(thread1);
        LockSupport.unpark(thread2);

    }

    /**
     *  Due to the different underlying implementation mechanisms ( Compared with others waiting Methods ), It can't be done directly Object.wait(), Otherwise, the following exception will be thrown 
     * @exception java.lang.IllegalMonitorStateException
     * object.wait() Conduct wait Methods , It's direct to it wait_set To operate 
     */
    private static void threadStateWithException() {
        Thread thread1 = new Thread(() -> {
            try {
                ThreadState.class.wait(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        });

        thread1.start();
        LockSupport.parkNanos(1000000000);
        printThreadState(thread1);

    }

    /**
     * Object.wait() Use 
     */
    private static void threadStateTest3() {
        Thread thread1 = new Thread(() -> {
            synchronized (ThreadState.class) {
                try {
                    ThreadState.class.wait(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread1.start();
        LockSupport.parkNanos(1000000000);
        printThreadState(thread1);

    }

    /**
     *  determine LockSupport.parkNacos() Whether it can generate Time_Waiting state 
     */
    private static void threadStateTest2() {
        Thread thread1 = new Thread(() -> {
            LockSupport.parkNanos(2000000000);
        });

        thread1.start();
        printThreadState(thread1);
        LockSupport.parkNanos(1000000000);

        printThreadState(thread1);
    }

    /**
     *  You can see that except for Blocked All thread states other than 
     */
    private static void threadStateTest() {
        Thread thread1 = new Thread(() -> {
            synchronized (ThreadState.class) {
                // Runnable
                printThreadState(Thread.currentThread());

                // 1.Thread.sleep(time)
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
                // 2.Object.wait(time)
//                try {
//                    ThreadState.class.wait(2000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                // 3.Thread.join(time)
//                try {
//                    Thread.currentThread().join(2000);
//                } catch (InterruptedException e) {
//                    e.printStackTrace();
//                }
                // 4.LockSupport.parkNanos(time);
//            LockSupport.parkNanos(2000000000);
                // 5.LockSupport.parkUntil(timeStamp);
//            LockSupport.parkUntil(System.currentTimeMillis()+2000);

                LockSupport.park();
            }

        });
        thread1.setName("test_thread");

        // New
        printThreadState(thread1);

        thread1.start();
        LockSupport.parkNanos(1000000000);
        // Timed_waiting
        printThreadState(thread1);

        LockSupport.parkNanos(2000000000);
        // Waiting
        printThreadState(thread1);

        LockSupport.unpark(thread1);

        LockSupport.parkNanos(1000000000);
        // Terminated
        printThreadState(thread1);


    }

    private static void printThreadState(Thread thread) {
        System.out.println("current Thread(" + thread.getName()+":" + thread.getId() + ") state:" + thread.getState());
    }

}

There's a little bit of knowledge in the code , I won't go into that here . Interested partners , You can look at the notes for yourself , Self verification .

7、 ... and 、 Expand : System status ( Tristate & Pentamorphism )

The operating system includes process management , Job management , Document management, etc. . Among them, process management , Three state model and five state model are involved in system state .
among , The three state model consists of the following three states :

  • Ready state
  • Running state
  • Blocked state

The five state model contains the following five states :

  • Running state
  • Static ready state
  • Active ready state
  • The stationary blocking state
  • Active blocking state

Specific state switching, etc , You can read a blog I wrote before :
System architect - operating system

Last , I wish to make progress with you .

8、 ... and 、 appendix

Add :WAITTING/TIMED_WAITTING And BLOCKED The difference between

Actually , I've been struggling with this problem before .
The idea was WAITTING/TIMED_WAITTING By JVM Self sustaining , and BLOCKED It's maintained by the system . See the mainstream in the back HotSpot It maps threads to native threads of the system , So this idea is probably wrong .
So what's the difference between the two ?
Until I did in the example code above ,BLOCKED Thread in state , When other threads release their required locks , The thread is first converted to RUNNING state , And then into other states . This caught my attention .
Last in stackOverFlow An article from (Difference between WAIT and BLOCKED thread states) in , See this explanation :

The important difference between the blocked and wait states is the impact on the scheduler. A thread in a blocked state is contending for a lock; that thread still counts as something the scheduler needs to service, possibly getting factored into the scheduler's decisions about how much time to give running threads (so that it can give the threads blocking on the lock a chance).
Once a thread is in the wait state the stress it puts on the system is minimized, and the scheduler doesn't have to worry about it. It goes dormant until it receives a notification. Except for the fact that it keeps an OS thread occupied it is entirely out of play.
This is why using notifyAll is less than ideal, it causes a bunch of threads that were previously happily dormant putting no load on the system to get woken up, where most of them will block until they can acquire the lock, find the condition they are waiting for is not true, and go back to waiting. It would be preferable to notify only those threads that have a chance of making progress.
(Using ReentrantLock instead of intrinsic locks allows you to have multiple conditions for one lock, so that you can make sure the notified thread is one that's waiting on a particular condition, avoiding the lost-notification bug in the case of a thread getting notified for something it can't act on.)

In short , Namely CPU Time slices don't think about WAITTING/TIMED_WAITTING state .
however , although BLOCKED State thread cannot get CPU Time slice , But when the system is scheduled , Still think about BLOCKED Thread in state , Put it in the scheduling calculation .

If one of the partners knows something about this , I hope I can have a chat .

Reference resources

版权声明
本文为[The end of blood night]所创,转载请带上原文链接,感谢

Scroll to Top