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