Reading notes on Java multithreaded programming core technology second edition

1, Summary

This book is written in a very shallow way. It is more about cases. The ThreadLocal part is OK. The principle is basically covered

The following knowledge points are roughly summarized

2, Content

When to use multithreading?

  • block
  • Dependency. For example, the service is divided into two execution processes. When service A is blocked, the execution of service B does not depend on the execution result of service A

The start() method takes time because multiple steps are performed

  • Tell the operating system to create a Thread through the JVM
  • Open up memory through the system and create a Thread object using the createThread() function in the windows SDK
  • The operating system schedules the Thread object to determine the execution time
  • Thread executed successfully inside the operating system

Analyze threads using common commands

  • jps + jstack.exe: jps view all threads, and then jps -l process id
  • jmc.exe visual interface
  • jvisualvm.exe visual interface

Stop a thread

  • Use the exit flag to exit normally
  • Use the stop() method to forcibly terminate the thread. The same methods suspend() and remuse() are outdated methods. Unexpected results may occur when using them, because the process will not release the lock
  • Interrupt the thread using the interrupt() method
  • The yield() method pauses the current thread and abandons cpu resources, but the abandonment time is uncertain


  • In Java, the priority of threads is 1 ~ 10, a total of 10 levels
  • Thread priority is inherited. Thread A creates thread B, and their priority is the same

Daemon thread, there are two kinds of threads in Java

  • Non daemon thread: that is, user thread
  • Daemon thread: when the non daemon thread does not exist, it will be automatically destroyed, typically a garbage collection thread

Overview of synchronized keyword. Decompile the class file into bytecode using javap command

  • The method is synchronized. It is found that there is more ACC in front of the method_ SYNCHRONIZED
  • Synchronize code blocks and use monitorenter and monitorexit instructions for synchronization

be careful

  • For non static methods, the Object lock locks the Object instance Object of the current class. The lock is not the code of the current method or code block, but the first thread holding the method
  • If you use the synchronized modifier non static method in an X object, the X object is treated as a lock
  • Reentrant. Other synchronized of this class can always get the lock by calling within the synchronized modified code block and method
  • Added to the static method, the lock is the Class object of the current Class, which works on all object instances

volatile has three characteristics

  • visibility
  • Atomicity is not guaranteed: variables with volatile are not atomic to perform i + + operations, and need to be synchronized
  • Prohibit code reordering

Inter thread communication

  • Executing the not () method will not immediately release the lock, but executing the wait() method will immediately release the lock. The wake-up sequence is consistent with the wait sequence. In the producer consumer mode, it is not guaranteed whether the same or different types are awakened
  • The. join() method of the xxx thread instance is executed. It stops the execution of the thread where the current instance is located, executes the run method of the thread instance, and has the result of thread queuing
  • The wait() method releases the lock, while sleep() does not

ThreadLocal class

  • The main function is to put the data into the member variable Map of the current running thread. It does not store data itself as a bridge
  • The key in the Map stores the ThreadLocal object
  • There is an internal ThreadLocalMap in the Thread class, which corresponds to the creation of the member property threadLocals. When using set, the createMap() method will be called. The implementation of this method is in the ThreadLocal class
  • The get() method of the instance object that initially calls ThreadLocal returns null. You can inherit ThreadLocal and override the initialValue() method to set the initial value
  • ThreadLocal class cannot implement value inheritance. The parent Thread creating the child Thread will not pass the set value to the child Thread. InheritableThreadLocal can be used to reflect the inheritance of value, which inherits the Thread class

Inheritblethreadlocal implements the principle of value inheritance

  • inheritableThreadLocals and threadLocals are both member variables of Thread, starting with null
  • Inheritblethreadlocal inherits ThreadLocal, but there is no method. There is no @ Override above
  • Calling the set() method of the inheritblethreadlocal object is actually the method of calling threadLocals, because the set method is not rewritten, and the createMap() and getMap called inside the get() method are all self rewritten methods

The specific principle is:

  • The parent thread calls the set() method of the inheritablethreadlocal instance to save data to the inheritablethreadlocal container
  • Further, when creating a child thread, the child class actively refers to the inheritblethreadlocal value of its parent thread

package java.lang;
import java.lang.ref.*;

 * This class extends {@code ThreadLocal} to provide inheritance of values
 * from parent thread to child thread: when a child thread is created, the
 * child receives initial values for all inheritable thread-local variables
 * for which the parent has values.  Normally the child's values will be
 * identical to the parent's; however, the child's value can be made an
 * arbitrary function of the parent's by overriding the {@code childValue}
 * method in this class.
 * <p>Inheritable thread-local variables are used in preference to
 * ordinary thread-local variables when the per-thread-attribute being
 * maintained in the variable (e.g., User ID, Transaction ID) must be
 * automatically transmitted to any child threads that are created.
 * <p>Note: During the creation of a new {@link
 * Thread#Thread(ThreadGroup,Runnable,String,long,boolean) thread}, it is
 * possible to <i>opt out</i> of receiving initial values for inheritable
 * thread-local variables.
 * @author  Josh Bloch and Doug Lea
 * @see     ThreadLocal
 * @since   1.2

public class InheritableThreadLocal<T> extends ThreadLocal<T> {
     * Computes the child's initial value for this inheritable thread-local
     * variable as a function of the parent's value at the time the child
     * thread is created.  This method is called from within the parent
     * thread before the child is started.
     * <p>
     * This method merely returns its input argument, and should be overridden
     * if a different behavior is desired.
     * @param parentValue the parent thread's value
     * @return the child thread's initial value
    protected T childValue(T parentValue) {
        return parentValue;

     * Get the map associated with a ThreadLocal.
     * @param t the current thread
    ThreadLocalMap getMap(Thread t) {
       return t.inheritableThreadLocals;

     * Create the map associated with a ThreadLocal.
     * @param t the current thread
     * @param firstValue value for the initial entry of the table.
    void createMap(Thread t, T firstValue) {
        t.inheritableThreadLocals = new ThreadLocalMap(this, firstValue);

  • The child Thread assigns the table object of the parent Thread to the child Thread in the way of assignment. This process is automatically completed when creating the Thread object, as long as the inheritblethreadlocal of the parent Thread is not null
  • After the parent thread updates the data of inheritblethreadlocal, the child thread will not update. On the contrary, the update of the child thread will not affect the parent thread, but the property value pointed to by the pointer, such as an object, will become invalid. In addition, childValue() can be overridden to process the value inherited by the parent thread by the child thread

Use of Lock objects

  • The ReentrantLock class added in JDK1.5 has more functions, such as sniffing locking, multi-channel branching, etc
  • Interprocess communication requires the aid of await() and signal() of Condition class

Tags: Java Multithreading jar intellij-idea

Posted on Fri, 19 Nov 2021 15:58:49 -0500 by Sephiriz