1, Thread life cycle and five basic states
About the life cycle of threads in Java, first take a look at the following classic diagram:
The above figure basically covers the important knowledge points of multithreading in Java. After mastering the knowledge points in the figure above, you can basically master multithreading in Java. It mainly includes:
Java threads have seven basic states
New: the status of the thread that has not been started so far. The thread has just been created but has not yet started. For example: Thread t = new MyThread();
Runnable: when calling the start() method (t.start();) of the thread object, The thread enters the ready state. A thread in the ready state only indicates that it is ready to wait for the CPU to schedule execution at any time, not that it will execute immediately after t.start() is executed;
Running: when the CPU starts scheduling the thread in the ready state, the thread can really execute, that is, enter the running state. Note: the thread state is the only entry to the running state, that is, if a thread wants to enter the running state for execution, it must first be in the ready state;
Waiting indefinitely: Blocked in object's wait pool: when a thread is running, if the wait() method of an object is executed, the Java virtual machine will put the thread into the waiting pool of the object, which involves the content of "thread communication". Threads in this state will not be allocated processor execution time. They will wait to be awakened by other threads. The following methods will put the thread into an indefinite waiting state:
- Object::wait() method without timeout parameter set
- Thread::join() method without timeout parameter set
- LockSupport::park() method
Timed Waiting: threads in this state will not be allocated processor execution time, but they do not need to wait for other threads to wake up. After a certain time, they will wake up automatically by the system. The following methods will put the thread into the deadline waiting state:
- Thread::sleep() method
- Object::wait() method with timeout parameter set
- Thread::join() method with timeout parameter set
- LockSupport::parkNanos() method
- LockSupport::parkUntil() method
Blocked: when a thread in the running state tries to obtain the synchronization lock of an object due to a certain (when the thread is in the running state), if the synchronization lock of the object has been occupied by other threads, the Java virtual machine will put the thread into the lock pool of the object, which involves the content of "thread synchronization". [the thread fails to acquire the synchronized synchronization lock (because the lock is occupied by other threads)], temporarily gives up the right to use the CPU and stops execution. At this time, it enters the blocking state. Until it enters the ready state, it has the opportunity to be called by the CPU again to enter the running state.
The difference between "blocking state" and "waiting state": "blocking state" is waiting to obtain an exclusive lock, and this event will occur when another thread abandons the lock; The "waiting state" is waiting for a period of time, or the wake-up action occurs. When the program enters the synchronization area, the thread will enter the blocking state.
Dead: when the thread finishes executing or exits the run() method due to an exception, the thread ends its life cycle.
JVM thread status
In java.lang.Thread.State The status of the thread is defined in:
NEW
The status of threads that have not yet started. The thread has just been created but has not yet started.
RUNNABLE
The thread state of the runnable thread. The thread is executing in the JVM and may be waiting for other resources in the operating system, such as the processor.
BLOCKED
The thread state of a thread that is blocked and waiting for the monitor. A thread in a blocked state is waiting for the monitor lock to enter a synchronized block / method, or is calling object After wait, enter the synchronized block / method again.
In the Thread Dump log, it is usually displayed as Java lang.Thread. State: BLOCKED (on object monitor) .
WAITING
The thread state of a waiting thread. A thread is waiting indefinitely for another thread to perform a specific operation. The thread is waiting because it calls one of the following methods:
- Object without timeout Wait method, which is displayed in the log as Java lang.Thread. State: WAITING (on object monitor)
- Thread without timeout Join method
- LockSupport.park method, which is displayed in the log as Java lang.Thread. State: WAITING (parking)
TIMED_WAITING
The thread state of a waiting thread that specifies the waiting time. The thread is waiting for another thread to perform a specific operation, and the specified waiting time is set. The thread is in a timed waiting state because it calls one of the following methods:
- Thread.sleep method
- Object that specifies the timeout value Wait method
- Specifies the thread. Of the timeout value Join method
- LockSupport.parkNanos
- LockSupport.parkUntil
TERMINATED
The thread is in a terminated state.
According to the instructions in Java Doc, a can only be in one of the above states at a given time, and these states are the states of the JVM, independent of the thread state in the operating system.
JAVA virtual machine startup procedure steps:
(1) Main is the main thread at startup, that is, the program entry
(2) After the main function ends, the virtual machine will automatically start a DestroyJavaVM thread, which will wait for all user thread threads to exit (that is, only the daemon thread and DestroyJavaVM thread themselves are left, and the whole virtual machine will exit. At this time, the daemon thread will be terminated). Therefore, if you don't want the program to exit, just create a non daemon sub thread, Let the thread sleep continuously.
Thread creation
Thread class has a start method, that is, start the thread. The thread started will execute the run method of this class. Note: because a process needs to be executed when starting a thread, it is usually necessary to re implement the run method
End of thread
After the execution of the run module, it actively exits, or is forcibly terminated by other threads.
Through jstack PID > 1 txt
Thread status example
Waiting status example
"IoWaitThread" prio=6 tid=0x0000000007334800 nid=0x2b3c waiting on condition [0x000000000893f000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x00000007d5c45850> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:156) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:1987) at java.util.concurrent.LinkedBlockingDeque.takeFirst(LinkedBlockingDeque.java:440) at java.util.concurrent.LinkedBlockingDeque.take(LinkedBlockingDeque.java:629) at com.nbp.theplatform.threaddump.ThreadIoWaitState$IoWaitHandler2.run(ThreadIoWaitState.java:89) at java.lang.Thread.run(Thread.java:662)
In the above example, the IoWaitThread thread keeps waiting and receives messages from the LinkedBlockingQueue. If the LinkedBlockingQueue has no messages, the state of the thread will not change.
Blocking status example
"BLOCKED_TEST pool-1-thread-1" prio=6 tid=0x0000000006904800 nid=0x28f4 runnable [0x000000000785f000] java.lang.Thread.State: RUNNABLE at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:282) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:65) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:123) - locked <0x0000000780a31778> (a java.io.BufferedOutputStream) at java.io.PrintStream.write(PrintStream.java:432) - locked <0x0000000780a04118> (a java.io.PrintStream) at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:202) at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:272) at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:85) - locked <0x0000000780a040c0> (a java.io.OutputStreamWriter) at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:168) at java.io.PrintStream.newLine(PrintStream.java:496) - locked <0x0000000780a04118> (a java.io.PrintStream) at java.io.PrintStream.println(PrintStream.java:687) - locked <0x0000000780a04118> (a java.io.PrintStream) at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:44) - locked <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState) at com.nbp.theplatform.threaddump.ThreadBlockedState$1.run(ThreadBlockedState.java:7) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Locked ownable synchronizers: - <0x0000000780a31758> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) "BLOCKED_TEST pool-1-thread-2" prio=6 tid=0x0000000007673800 nid=0x260c waiting for monitor entry [0x0000000008abf000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:43) - waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState) at com.nbp.theplatform.threaddump.ThreadBlockedState$2.run(ThreadBlockedState.java:26) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Locked ownable synchronizers: - <0x0000000780b0c6a0> (a java.util.concurrent.locks.ReentrantLock$NonfairSync) "BLOCKED_TEST pool-1-thread-3" prio=6 tid=0x00000000074f5800 nid=0x1994 waiting for monitor entry [0x0000000008bbf000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadBlockedState.monitorLock(ThreadBlockedState.java:42) - waiting to lock <0x0000000780a000b0> (a com.nbp.theplatform.threaddump.ThreadBlockedState) at com.nbp.theplatform.threaddump.ThreadBlockedState$3.run(ThreadBlockedState.java:34) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:662) Locked ownable synchronizers: - <0x0000000780b0e1b8> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
In the above example, BLOCKED_TEST pool-1-thread-1 thread occupied < 0x0000000780a000b0 > lock, but BLOCKED_TEST pool-1-thread-2 and BLOCKED_TEST pool-1-thread-3 threads is waiting to acquire the lock.
Deadlock status example
"DEADLOCK_TEST-1" daemon prio=6 tid=0x000000000690f800 nid=0x1820 waiting for monitor entry [0x000000000805f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197) - waiting to lock <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182) - locked <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135) Locked ownable synchronizers: - None "DEADLOCK_TEST-2" daemon prio=6 tid=0x0000000006858800 nid=0x17b8 waiting for monitor entry [0x000000000815f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197) - waiting to lock <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182) - locked <0x00000007d58f5e60> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135) Locked ownable synchronizers: - None "DEADLOCK_TEST-3" daemon prio=6 tid=0x0000000006859000 nid=0x25dc waiting for monitor entry [0x000000000825f000] java.lang.Thread.State: BLOCKED (on object monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.goMonitorDeadlock(ThreadDeadLockState.java:197) - waiting to lock <0x00000007d58f5e48> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.monitorOurLock(ThreadDeadLockState.java:182) - locked <0x00000007d58f5e78> (a com.nbp.theplatform.threaddump.ThreadDeadLockState$Monitor) at com.nbp.theplatform.threaddump.ThreadDeadLockState$DeadlockThread.run(ThreadDeadLockState.java:135) Locked ownable synchronizers: - None
In the above example, thread A needs to obtain the lock of thread B to continue its task, but thread B also needs to obtain the lock of thread A to continue its task. In thread dump, you can see deadlock_ The TEST-1 thread holds the 0x00000007d58f5e48 lock and attempts to acquire the 0x00000007d58f5e60 lock. You can also see deadlock_ The test-2 thread holds 0x00000007d58f5e60 and attempts to obtain 0x00000007d58f5e78 while deadlock_ The Test-3 thread holds 0x00000007d58f5e78 and is trying to acquire the 0x00000007d58f5e48 lock. As you can see, each thread is waiting to acquire the lock of another thread. This state will not be changed until A thread discards its lock.
Example of Runnable status with infinite wait
"socketReadThread" prio=6 tid=0x0000000006a0d800 nid=0x1b40 runnable [0x00000000089ef000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:129) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:264) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:306) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:158) - locked <0x00000007d78a2230> (a java.io.InputStreamReader) at sun.nio.cs.StreamDecoder.read0(StreamDecoder.java:107) - locked <0x00000007d78a2230> (a java.io.InputStreamReader) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:93) at java.io.InputStreamReader.read(InputStreamReader.java:151) at com.nbp.theplatform.threaddump.ThreadSocketReadState$1.run(ThreadSocketReadState.java:27) at java.lang.Thread.run(Thread.java:662)
In the above example, the state of the thread is RUNNABLE, but it is found in the following stack log that the socketReadThread thread thread is waiting for the socket to be read indefinitely. Therefore, it is not possible to determine whether the thread is in the blocking state simply by the state of the thread. It should be analyzed according to the detailed stack information.