1. Class definition

public class Thread implements Runnable
Copy the code

You can see this in the class definition

  • Thread implements the Runnable interface

    Now look at the definition of Runnable

    @FunctionalInterface
    public interface Runnable {
        public abstract void run(a);
    }
    Copy the code
    • Runnable is a functional interface (interface with only one method)
    • Runnable has only one run method

2. Field attributes

    // The name of the thread, volatile
    private volatile String name;
	// Priority of the thread
    private int            priority;
    private Thread         threadQ;
    private long           eetop;
	// Whether the current thread is single_step
	private boolean     single_step;
	// Whether the current thread is a daemon thread or a user thread, the default is user thread
	// In the current JVM instance, daemons work as long as there are users. If no user thread exists, the daemon thread terminates with the JVM
	private boolean     daemon = false;
	/ / the JVM
	private boolean     stillborn = false;
	// The current Thread will run the run Thread is actually a Runnable
	private Runnable target;
	// The thread group of the current thread
	private ThreadGroup group;
	// The class loader for the context object in the current thread
	private ClassLoader contextClassLoader;
	/* The inherited AccessControlContext of this thread */
    private AccessControlContext inheritedAccessControlContext;
	// Number of threads
	private static int threadInitNumber;
	//ThreadLocal Specifies the actual container for storing data
	/ / copies of ThreadLocal content is stored in each thread in a ThreadLocal. ThreadLocalMap inside
	ThreadLocal.ThreadLocalMap threadLocals = null;
	ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
	// The number of current thread stacks
	private long stackSize;
	private long nativeParkEventPointer;
	// Id of the current thread
	private long tid;
	// To generate the thread ID
	private static long threadSeqNumber;
	// The current status of the thread, volatile
	private volatile int threadStatus = 0;

	volatile Object parkBlocker;
	// Set Interrupt Status when an I/O time-consuming operation is interrupted
	private volatile Interruptible blocker;
	// Is the object of the sync Blocker service
	private final Object blockerLock = new Object();

	// The minimum thread priority is 1
	public final static int MIN_PRIORITY = 1;
	// The default thread priority is 5
	public final static int NORM_PRIORITY = 5;
	The maximum thread priority is 10
	public final static int MAX_PRIORITY = 10;
Copy the code

3. Construction method

// Default constructor
public Thread(a) {
    	// Call init to initialize
        init(null.null."Thread-" + nextThreadNum(), 0);
    }

// Pass in a Runnable object
public Thread(Runnable target) {
    	// Call init to initialize
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }

// Pass in a Runnable object and an AccessControlContext object
Thread(Runnable target, AccessControlContext acc) {
    	// Call init to initialize
        init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
    }

// Pass a Runnable object and a ThreadGroup object
public Thread(ThreadGroup group, Runnable target) {
    	// Call init to initialize
        init(group, target, "Thread-" + nextThreadNum(), 0);
    }
// Pass in the name of the thread
public Thread(String name) {
    	// Call init to initialize
        init(null.null, name, 0);
    }
// Pass in the name of the thread group and thread
public Thread(ThreadGroup group, String name) {
    	// Call init to initialize
        init(group, null, name, 0);
    }
// Pass in a Runnable object and the name of the thread
public Thread(Runnable target, String name) {
    	// Call init to initialize
        init(null, target, name, 0);
    }
// Pass in the name of the thread group, Runnable object, and thread
public Thread(ThreadGroup group, Runnable target, String name) {
    	// Call init to initialize
        init(group, target, name, 0);
    }
// Pass in the thread group, Runnable object, thread name, stack size
public Thread(ThreadGroup group, Runnable target, String name,
                  long stackSize) {
    	// Call init to initialize
        init(group, target, name, stackSize);
    }
Copy the code

You can see from the constructor

  • At the heart of threads is Runnable
  • The constructors all call init to initialize
  • A thread has a thread group and a thread name
  • The default name for a Thread is “Thread-” followed by a string of numbers
  • Thread initialization can also pass in stack size, AccessControlContext AccessControlContext object

Method 4.

RegisterNatives method

// Static native method, make sure this method is the first thing to do
// This method should be registered to the JVM or something, I guess
private static native void registerNatives(a);
    static {
        registerNatives();
    }
Copy the code

NextThreadNum method

// Get the next thread number
// This is a statically synchronized method
private static synchronized int nextThreadNum(a) {
    	// Return threadInitNumber directly and increment threadInitNumber by 1
        return threadInitNumber++;
    }
Copy the code

NextThreadID method

// Get the next thread ID
// This is a statically synchronized method
private static synchronized long nextThreadID(a) {
    	// Add threadSeqNumber by 1 and return
        return ++threadSeqNumber;
    }
Copy the code

The init method

// Initialize method
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize) {
    	// Tune the following initialization methods
        init(g, target, name, stackSize, null.true);
    }
// This is the actual initialization method for Thread
private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc,
                      boolean inheritThreadLocals) {
    	// Check the parameters
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
	    // Set the current thread name
        this.name = name;
		// Get the current calling thread, making the current calling thread the parent thread
        Thread parent = currentThread();
    	// Get the security controller
        SecurityManager security = System.getSecurityManager();
        if (g == null) {
            // If the thread group passed in is null
            if(security ! =null) {
                // If the security controller is not null
                // Thread group set to the thread group of the current thread
                /** public ThreadGroup getThreadGroup() { return Thread.currentThread().getThreadGroup(); } * /
                g = security.getThreadGroup();
            }

            if (g == null) {
                // If the thread group of the security controller is null
                // The thread group that uses the parent threadg = parent.getThreadGroup(); }}/* checkAccess regardless of whether or not threadgroup is explicitly passed in. */
    	// Check whether the thread group requires access
        g.checkAccess();

        // Check whether you have request permission
        if(security ! =null) {
            if(isCCLOverridden(getClass())) { security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); }}// Increase the number of unstarted threads in the thread group by 1
        g.addUnstarted();
		// Set the thread group to the thread group obtained above
        this.group = g;
    	// Set the thread daemon to Damon of the parent thread
        this.daemon = parent.isDaemon();
    	// Set the thread priority to the parent thread priority
        this.priority = parent.getPriority();
    	// Set the inline class loader
        if (security == null || isCCLOverridden(parent.getClass()))
            this.contextClassLoader = parent.getContextClassLoader();
        else
            this.contextClassLoader = parent.contextClassLoader;
        this.inheritedAccessControlContext = acc ! =null ? acc : AccessController.getContext();
    	// Set the Runnable object to the Runnable object passed in
        this.target = target;
    	// Sets the priority of the thread to that of the current object
        setPriority(priority);
        if(inheritThreadLocals && parent.inheritableThreadLocals ! =null)
            this.inheritableThreadLocals =
                ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
        /* Stash the specified stack size in case the VM cares */
    	// Set the stack size
        this.stackSize = stackSize;
		// Set the thread ID
        tid = nextThreadID();
    }
Copy the code

SetPriority method

// Set the priority of the thread
public final void setPriority(int newPriority) {
    	// The thread group of the current thread
        ThreadGroup g;
    	// Check access permissions
        checkAccess();
    	// Check parameters
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if((g = getThreadGroup()) ! =null) {
            // If the current thread group is not null
            if (newPriority > g.getMaxPriority()) {
                // The new priority passed in is greater than the maximum priority of the thread group
                // Set the new priority to the highest priority of the thread group
                newPriority = g.getMaxPriority();
            }
            // Set the priority of the threadsetPriority0(priority = newPriority); }}// The real thread priority setting method is native
private native void setPriority0(int newPriority);
Copy the code

GetPriority method

// Get the priority of the current thread
public final int getPriority(a) {
        return priority;
    }
Copy the code

CurrentThread method

// Get the current thread. This is a native method
public static native Thread currentThread(a);
Copy the code

Yield method

// The scheduler is free to ignore the hint that the current process gives up the current process
// It is possible that the current thread gives up execution and then grabs Cpu resources to continue execution
//yield puts the current thread into a ready state, but it can still compete for resources
public static native void yield(a);
Copy the code

Sleep method

// How many millimeters to sleep the current thread
// The current thread does not relinquish the lock of the object to other threads
public static native void sleep(long millis) throws InterruptedException;

public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }
        if (nanos >= 500000|| (nanos ! =0 && millis == 0)) {
            millis++;
        }
    	// The result is the same method as above, with nanoseconds instead of millimeters
        sleep(millis);
    }

Copy the code

Clone method

// Does not support cloning, directly throw an exception
// This is something to learn. There are many such operations in the JDK. Subclasses do not support superclass methods and throw exceptions directly
@Override
    protected Object clone(a) throws CloneNotSupportedException {
        throw new CloneNotSupportedException();
    }
Copy the code

The start method

// Start a thread
// Just change the thread state from NEW to Runnable
// Do not execute immediately, it depends on whether the CPU resources can be grabbed
public synchronized void start(a) {
        if(threadStatus ! =0)
            // The NEW state is 0
            // If the current thread is not NEW, an exception is thrown
            throw new IllegalThreadStateException();

        // Wake up the thread group and add the current thread to the thread array of the thread group
    	// Increase the number of threads in the thread group by 1 and decrease the number of unstarted threads in the thread group by 1
        group.add(this);
		// Set the startup state to false
        boolean started = false;
        try {
            // This is a native method
            start0();
            // The thread was successfully started, setting the startup state to true
            started = true;
        } finally {
            try {
                if(! started) {// If startup fails, notify the thread group to take action
                    group.threadStartFailed(this); }}catch (Throwable ignore) {
               
            }
        }
    }
	// The real way to start a thread is a native method
	// Start thread operations are handled by the JVM
    private native void start0(a);
Copy the code

Run method

// This should be the JVM's underlying callback
@Override
    public void run(a) {
        // Direct execution to the Runnable object
        if(target ! =null) { target.run(); }}Copy the code

The exit way

// The system calls exit to reclaim the resource before Thread exits
private void exit(a) {
        if(group ! =null) {
            // If thread group is not null
            // Wake up other threads in the thread group
            group.threadTerminated(this);
            group = null;
        }
        /* Aggressively null out all reference fields: see bug 4006245 */
        target = null;
        /* Speed the release of some of these resources */
        threadLocals = null;
        inheritableThreadLocals = null;
        inheritedAccessControlContext = null;
        blocker = null;
        uncaughtExceptionHandler = null;
    }
Copy the code

Stop method

// Force the current thread to stop
public final void stop(a) {
    	// Get the security manager
        SecurityManager security = System.getSecurityManager();
        if(security ! =null) {
            // If the security manager is not null
            // Check permissions
            checkAccess();
            if (this! = Thread.currentThread()) {// if not called by the current thread
                // Check permissionssecurity.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION); }}if(threadStatus ! =0) {
            // If the current thread is not NEW, it may be suspended
            // Call the resume method to resume a suspended thread
            resume(); // Wake up thread if it was suspended; no-op otherwise
        }

        // THE VM can manipulate all states
    	// Execute with stop0
        stop0(new ThreadDeath());
    }
// Force the current thread to stop. This is a native method
private native void stop0(Object o);
Copy the code

Resume method

// Resuming a suspended thread. If the thread is not paused, no other operations are done
@Deprecated
    public final void resume(a) {
        // Check permissions
        checkAccess();
        // Call reume0 to resume suspended threads
        resume0();
    }
// Resuming suspended threads is a nateive method
private native void resume0(a);
Copy the code

Interrupt method

// Interrupt the thread
public void interrupt(a) {
        if (this! = Thread.currentThread())// if not called by the current thread
            // Check permissions
            checkAccess();
		/ / synchronize blockerLock
    	// The synchronization block contains blockers, because blockerLock is used to synchronize Blockers
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if(b ! =null) {
                // If blocker is not null, I/O is currently blocked
                // Set only the interrupt state
                interrupt0();           
                // Call Blocker's InterRUP method after setting Interrupt Status
                b.interrupt(this);
                return; }}// Set interrupt Status
        interrupt0();
    }
// Set interrupt status this is a native method
private native void interrupt0(a);
Copy the code

Interrupted method

// Tests whether the calling thread is interrupted, which is a static method
public static boolean interrupted(a) {
    	// Call the isInterrupted method of the current thread to test
        return currentThread().isInterrupted(true);
    }
Copy the code

IsInterrupted method

// Tests whether the current thread is interrupted
public boolean isInterrupted(a) {
    	// Call the isInterrupted method directly
        return isInterrupted(false);
    }
// Test whether the thread breaks, which is a native method
//ClearInterrupted true resets interrupted state, false does not reset interrupted state
 private native boolean isInterrupted(boolean ClearInterrupted);
Copy the code

Suspend method

// Suspend the thread
@Deprecated
    public final void suspend(a) {
        // Check permissions
        checkAccess();
        Call susupend0 to suspend the thread
        suspend0();
    }
// Suspend the thread, which is a native method
private native void suspend0(a);
Copy the code

Elegantly-named setName method

// Set the thread name, which is a synchronization method
public final synchronized void setName(String name) {
    	// Check permissions
        checkAccess();
    	// Check parameters
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
		// Assign a value to the name attribute
        this.name = name;
        if(threadStatus ! =0) {
            // If the current thread is not NEW, call setNativeNamesetNativeName(name); }}// Set the thread name
private native void setNativeName(String name);
Copy the code

GetName method

// Get the thread name
public final String getName(a) {
        return name;
    }
Copy the code

GetThreadGroup method

// Get the thread group of the thread
public final ThreadGroup getThreadGroup(a) {
        return group;
    }
Copy the code

ActiveCount method

// Returns the current thread group and subthread group, the number of active threads, and an estimate
public static int activeCount(a) {
        return currentThread().getThreadGroup().activeCount();
    }
Copy the code

Enumerate method

// Copies the active threads of the current thread group and its child thread groups into the specified array
public static int enumerate(Thread tarray[]) {
        return currentThread().getThreadGroup().enumerate(tarray);
    }
Copy the code

The join method

// Wait for the thread to finish
public final void join(a) throws InterruptedException {
    	// Call the following method
        join(0);
    }
// Wait until the specified maximum time or the thread finishes executing
public final synchronized void join(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }
        if (nanos >= 500000|| (nanos ! =0 && millis == 0)) {
            millis++;
        }
    	// Convert nanoseconds to milliseconds
    	// Call the following method
        join(millis);
    }
// This is the real join method
Wait until the specified number of milliseconds, or until the current thread completes
public final synchronized void join(long millis)
    throws InterruptedException {
        long base = System.currentTimeMillis();
        long now = 0;
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        if (millis == 0) {
            // Wait time is not specified
            // Continue the while loop until the current thread terminates before executing the calling thread
            while (isAlive()) {
                wait(0); }}else {
            // Specify the wait time
            // The while loop determines whether the current thread is finished
            while (isAlive()) {
                long delay = millis - now;
                // If the waiting time exceeds the specified time, exit and continue executing the calling thread
                if (delay <= 0) {
                    break; } wait(delay); now = System.currentTimeMillis() - base; }}}Copy the code

SetDaemon method

// Set whether the thread is a daemon thread or a user thread
// must be called before start
public final void setDaemon(boolean on) {
    	// Check permissions
        checkAccess();
    	// Throw an exception if the thread is running
        if (isAlive()) {
            throw new IllegalThreadStateException();
        }
    	// Set the thread flag
        daemon = on;
    }
Copy the code

IsDaemon method

// Tests whether the current thread is a user thread or a daemon thread
public final boolean isDaemon(a) {
        return daemon;
    }
Copy the code

Method checkAccess

// Check permissions
// Determine whether the current running thread (calling thread) has permission to modify the thread
public final void checkAccess(a) {
    	// Get the security manager
        SecurityManager security = System.getSecurityManager();
        if(security ! =null) {
            // If the security manager is not null
            // Call the security manager's checkAccess method
            security.checkAccess(this); }}Copy the code

The toString method

The toString method of thread has the thread name, priority, and thread group name
public String toString(a) {
        ThreadGroup group = getThreadGroup();
        if(group ! =null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                           group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                            "" + "]"; }}Copy the code

GetId method

// Get the thread ID
public long getId(a) {
        return tid;
    }
Copy the code

5. The inner class

Thread state

public enum State {
        /** * Thread state for a thread which has not yet started. */
    	// The initial state is the state when new is generated but start is not called
        NEW,

        /** * Thread state for a runnable thread. A thread in the runnable * state is executing in the Java virtual machine but it may * be waiting for other resources from the operating system * such as processor. */
    	// Run time state, or ready state, after calling start
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
    	// Waiting for the object lock to be acquired
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
    	// Waiting to be woken up
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
    	// Wait for someone to wake up, but set the maximum wait time state
        TIMED_WAITING,

        /** * Thread state for a terminated thread. * The thread has completed execution. */
    	// Status of the run method
        TERMINATED;
    }
Copy the code