概述
PS. 文本将Thread中的每个字段和方法都大概过了一边,大部分方法没有细究内部的实现原理,这个后期有余力必然细细品味,搞清楚来龙去脉。
线程问题,是人工和机器拉开差距的一个弯道:做好一件事情 ,人一时间只能专注一件事情,而机器不同,(在这片博客的时间点,计算机CPU核数 与 并行线程数成正比 4核CPU ==4个并行线程 目前都是超核CPU:4核CPU ==8个并行线程)可以同时执行多个事情。
JDK中的线程类:Thread
Thread类源码分析
Thread实现Runnable接口,实现run方法
/* Make sure registerNatives is the first thing <clinit> does. */
private static native void registerNatives();
static {
registerNatives();
}
从上面的代码中看到定义了一个静态初始化块,我们知道当创建Java对象时,系统总是先调用静态初始化块
在上面的静态初始化块中调用了registerNatives()方法,并且使用了private来修饰,表面这个方法是私有的并不被外部调用。
在Java中使用native关键字修饰的方法,说明此方法并不是由Java中完成的,而是通过C/C++来完成的,并被编译成.dll,之后才由Java调用。方法的具体实现是在dll文件中,当然对于不同平台实现的细节也有所不同,以上registerNatives()方法主要作用就是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦
//线程名字
private volatile String name;
//线程优先级
private int priority;
//1.未知 2.该类未使用,而且一直为null
private Thread threadQ;
//1.未知 2.该类未使用,是一串挺大的值
private long eetop;
//1.是否是单步执行此线程 2.该类未使用 3.白话文:要不要将该线程设置为一个原子操作
private boolean single_step;
//1.是否设置成守护线程 默认false:非守护线程
private boolean daemon = false;
//在JVM中的状态 判断是否夭折 默认是false:非夭折
private boolean stillborn = false;
//Runnable 运行体 具体要执行的内容
private Runnable target;
/* The group of this thread */
//线程组
private ThreadGroup group;
//类加载器,说来话长:https://blog.csdn.net/briblue/article/details/54973413
private ClassLoader contextClassLoader;
/* The inherited AccessControlContext of this thread */
//与权限控制相关的属性 --没理解清楚,不做过多说明
private AccessControlContext inheritedAccessControlContext;
//线程初始编号 -- 用于自动编号匿名线程
private static int threadInitNumber;
//这里用静态的且同步的方法就是保证线程不会同名
private static synchronized int nextThreadNum() {
return threadInitNumber++;
}
//以下涉及到ThreadLocal类请查看-> https://www.cnblogs.com/dolphin0520/p/3920407.html
/* ThreadLocal values pertaining to this thread. This map is maintained
* by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null;
/*
* InheritableThreadLocal values pertaining to this thread. This map is
* maintained by the InheritableThreadLocal class.
*/
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
//此线程请求的堆栈大小,如果创建者未指定堆栈大小,则为0。 虚拟机可以用这个号码做任何喜欢的事情; 一些虚拟机会忽略它。
private long stackSize;
//线程终止后持久存在的JVM私有状态。
private long nativeParkEventPointer;
//线程ID
private long tid;
//用于生成线程ID
private static long threadSeqNumber;
//工具的Java线程状态,已初始化以指示线程“尚未启动”
private volatile int threadStatus = 0;
//tid的由来 和 threaddeqNumber的作用
private static synchronized long nextThreadID() {
return ++threadSeqNumber;
}
//线程阻塞功能的根源
volatile Object parkBlocker;
//在可中断的I / O操作中阻塞此线程的对象(如果有)。 设置此线程的中断状态后,应调用阻塞程序的中断方法。 ---没理解,有人理解了留个言呗
private volatile Interruptible blocker;
private final Object blockerLock = new Object();
/* 设置阻止字段; 调用 sun.misc.SharedSecrets from java.nio code
*/
void blockedOn(Interruptible b) {
synchronized (blockerLock) {
blocker = b;
}
}
//线程执行的优先级 1~10 ,5是默认值,优先级概念是执行的概率,没有说高优先级一定先执行
public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;
//获取当前线程
public static native Thread currentThread();
//当前线程放弃执行机会,从运行状态转到可运行状态
public static native void yield();
//当前线程进入休眠
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++;
}
sleep(millis);
}
//初始化--私有方法
private void init(ThreadGroup g, Runnable target, String name,
long stackSize) {
init(g, target, name, stackSize, null, true);
}
//初始化--私有方法
private void init(ThreadGroup g, Runnable target, String name,
long stackSize, AccessControlContext acc,
boolean inheritThreadLocals) {
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
Thread parent = currentThread();
SecurityManager security = System.getSecurityManager();
if (g == null) {
/* Determine if it's an applet or not */
/* If there is a security manager, ask the security manager
what to do. */
if (security != null) {
g = security.getThreadGroup();
}
/* If the security doesn't have a strong opinion of the matter
use the parent thread group. */
if (g == null) {
g = parent.getThreadGroup();
}
}
/* checkAccess regardless of whether or not threadgroup is
explicitly passed in. */
g.checkAccess();
/*
* Do we have the required permissions?
*/
if (security != null) {
if (isCCLOverridden(getClass())) {
security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
g.addUnstarted();
this.group = g;
this.daemon = parent.isDaemon();
this.priority = parent.getPriority();
if (security == null || isCCLOverridden(parent.getClass()))
this.contextClassLoader = parent.getContextClassLoader();
else
this.contextClassLoader = parent.contextClassLoader;
this.inheritedAccessControlContext =
acc != null ? acc : AccessController.getContext();
this.target = target;
setPriority(priority);
if (inheritThreadLocals && parent.inheritableThreadLocals != null)
this.inheritableThreadLocals =
ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
/* Stash the specified stack size in case the VM cares */
this.stackSize = stackSize;
/* Set thread ID */
tid = nextThreadID();
}
//重写超类 Object类 的 clone() 方法
@Override
protected Object clone() throws CloneNotSupportedException {
throw new CloneNotSupportedException();
}
//Thread构造方法
public Thread() {
init(null, null, "Thread-" + nextThreadNum(), 0);
}
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
Thread(Runnable target, AccessControlContext acc) {
init(null, target, "Thread-" + nextThreadNum(), 0, acc, false);
}
public Thread(ThreadGroup group, Runnable target) {
init(group, target, "Thread-" + nextThreadNum(), 0);
}
public Thread(String name) {
init(null, null, name, 0);
}
public Thread(ThreadGroup group, String name) {
init(group, null, name, 0);
}
public Thread(Runnable target, String name) {
init(null, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name) {
init(group, target, name, 0);
}
public Thread(ThreadGroup group, Runnable target, String name,
long stackSize) {
init(group, target, name, stackSize);
}
//开启一个新线程的开发,一个thread实例只能开启一个线程
public synchronized void start() {
//检查线程是否已经被创建 threadStatus=0 表示线程未被创建
if (threadStatus != 0)
throw new IllegalThreadStateException();
//添加线程
group.add(this);
boolean started = false;
try {
start0();
started = true;
} finally {
try {
if (!started) {
group.threadStartFailed(this);
}
} catch (Throwable ignore) {
/* do nothing. If start0 threw a Throwable then
it will be passed up the call stack */
}
}
}
//native方法
private native void start0();
//继承 Thread 类需要重写run 方法
@Override
public void run() {
if (target != null) {
target.run();
}
}
//线程退出并且清理对应的内存
private void exit() {
if (group != null) {
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;
}
@Deprecated
public final void stop() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
checkAccess();
if (this != Thread.currentThread()) {
security.checkPermission(SecurityConstants.STOP_THREAD_PERMISSION);
}
}
// A zero status value corresponds to "NEW", it can't change to
// not-NEW because we hold the lock.
if (threadStatus != 0) {
resume(); // Wake up thread if it was suspended; no-op otherwise
}
// The VM can handle all thread states
stop0(new ThreadDeath());
}
@Deprecated
public final synchronized void stop(Throwable obj) {
throw new UnsupportedOperationException();
}
//发送打断信号,尝试打断thread实例创建的线程 <revised 6.0> <spec JSR-51>
public void interrupt() {
if (this != Thread.currentThread())
checkAccess();
synchronized (blockerLock) {
Interruptible b = blocker;
if (b != null) {
interrupt0(); // Just to set the interrupt flag
b.interrupt(this);
return;
}
}
interrupt0();
}
//静态方法,判断当前线程是否被打断,true表示打断成功 <revised 6.0>
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
//实例化方法,判断this.线程是否被打断,true表示打断成功
public boolean isInterrupted() {
return isInterrupted(false);
}
//native方法
private native boolean isInterrupted(boolean ClearInterrupted);
//销毁线程 <Deprecated>
public void destroy() {
throw new NoSuchMethodError();
}
//判断线程是否还活着
public final native boolean isAlive();
// <Deprecated>
public final void suspend() {
checkAccess();
suspend0();
}
// <Deprecated>
public final void resume() {
checkAccess();
resume0();
}
//设置线程执行优先级
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
//获取线程执行优先级
public final int getPriority() {return priority;}
//设置线程name
public final synchronized void setName(String name) {
checkAccess();
if (name == null) {
throw new NullPointerException("name cannot be null");
}
this.name = name;
if (threadStatus != 0) {
setNativeName(name);
}
}
//获取线程名字
public final String getName() { return name;}
//获取线程组
public final ThreadGroup getThreadGroup() {return group;}
//获取活跃的线程个数
public static int activeCount() {
return currentThread().getThreadGroup().activeCount();
}
public static int enumerate(Thread tarray[]) {
return currentThread().getThreadGroup().enumerate(tarray);
}
//join方法 场景:在线程A中启动线程B,B.join(1000)执行之后,要等B线程run-1s之后A才可能执行
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) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
//join方法 同上
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++;
}
join(millis);
}
// Waits for this thread to die.
public final void join() throws InterruptedException {
join(0);
}
//将当前线程的堆栈跟踪打印到标准错误流 This method is used only for debugging.
public static void dumpStack() {
new Exception("Stack trace").printStackTrace();
}
//将当前线程设置成启动线程的守护线程
public final void setDaemon(boolean on) {
checkAccess();
if (isAlive()) {
throw new IllegalThreadStateException();
}
daemon = on;
}
//是否是守护线程
public final boolean isDaemon() {
return daemon;
}
//确定当前运行的线程是否具有修改此线程的权限。 如果有安全管理器,则以此线程作为其参数调用其checkAccess方法。 这可能会导致抛出SecurityException
public final void checkAccess() {
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkAccess(this);
}
}
public String toString() {
ThreadGroup group = getThreadGroup();
if (group != null) {
return "Thread[" + getName() + "," + getPriority() + "," +
group.getName() + "]";
} else {
return "Thread[" + getName() + "," + getPriority() + "," +
"" + "]";
}
}
@CallerSensitive
public ClassLoader getContextClassLoader() {
if (contextClassLoader == null)
return null;
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
ClassLoader.checkClassLoaderPermission(contextClassLoader,
Reflection.getCallerClass());
}
return contextClassLoader;
}
public void setContextClassLoader(ClassLoader cl) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
contextClassLoader = cl;
}
/**
* Returns <tt>true</tt> if and only if the current thread holds the
* monitor lock on the specified object.
*
* <p>This method is designed to allow a program to assert that
* the current thread already holds a specified lock:
* <pre>
* assert Thread.holdsLock(obj);
* </pre>
*
* @param obj the object on which to test lock ownership
* @throws NullPointerException if obj is <tt>null</tt>
* @return <tt>true</tt> if the current thread holds the monitor lock on
* the specified object.
* @since 1.4
*/
public static native boolean holdsLock(Object obj);
private static final StackTraceElement[] EMPTY_STACK_TRACE
= new StackTraceElement[0];
/**
* Returns an array of stack trace elements representing the stack dump
* of this thread. This method will return a zero-length array if
* this thread has not started, has started but has not yet been
* scheduled to run by the system, or has terminated.
* If the returned array is of non-zero length then the first element of
* the array represents the top of the stack, which is the most recent
* method invocation in the sequence. The last element of the array
* represents the bottom of the stack, which is the least recent method
* invocation in the sequence.
*
* <p>If there is a security manager, and this thread is not
* the current thread, then the security manager's
* <tt>checkPermission</tt> method is called with a
* <tt>RuntimePermission("getStackTrace")</tt> permission
* to see if it's ok to get the stack trace.
*
* <p>Some virtual machines may, under some circumstances, omit one
* or more stack frames from the stack trace. In the extreme case,
* a virtual machine that has no stack trace information concerning
* this thread is permitted to return a zero-length array from this
* method.
*
* @return an array of <tt>StackTraceElement</tt>,
* each represents one stack frame.
*
* @throws SecurityException
* if a security manager exists and its
* <tt>checkPermission</tt> method doesn't allow
* getting the stack trace of thread.
* @see SecurityManager#checkPermission
* @see RuntimePermission
* @see Throwable#getStackTrace
*
* @since 1.5
*/
public StackTraceElement[] getStackTrace() {
if (this != Thread.currentThread()) {
// check for getStackTrace permission
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(
SecurityConstants.GET_STACK_TRACE_PERMISSION);
}
// optimization so we do not call into the vm for threads that
// have not yet started or have terminated
if (!isAlive()) {
return EMPTY_STACK_TRACE;
}
StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
StackTraceElement[] stackTrace = stackTraceArray[0];
// a thread that was alive during the previous isAlive call may have
// since terminated, therefore not having a stacktrace.
if (stackTrace == null) {
stackTrace = EMPTY_STACK_TRACE;
}
return stackTrace;
} else {
// Don't need JVM help for current thread
return (new Exception()).getStackTrace();
}
}
/**
* Returns a map of stack traces for all live threads.
* The map keys are threads and each map value is an array of
* <tt>StackTraceElement</tt> that represents the stack dump
* of the corresponding <tt>Thread</tt>.
* The returned stack traces are in the format specified for
* the {@link #getStackTrace getStackTrace} method.
*
* <p>The threads may be executing while this method is called.
* The stack trace of each thread only represents a snapshot and
* each stack trace may be obtained at different time. A zero-length
* array will be returned in the map value if the virtual machine has
* no stack trace information about a thread.
*
* <p>If there is a security manager, then the security manager's
* <tt>checkPermission</tt> method is called with a
* <tt>RuntimePermission("getStackTrace")</tt> permission as well as
* <tt>RuntimePermission("modifyThreadGroup")</tt> permission
* to see if it is ok to get the stack trace of all threads.
*
* @return a <tt>Map</tt> from <tt>Thread</tt> to an array of
* <tt>StackTraceElement</tt> that represents the stack trace of
* the corresponding thread.
*
* @throws SecurityException
* if a security manager exists and its
* <tt>checkPermission</tt> method doesn't allow
* getting the stack trace of thread.
* @see #getStackTrace
* @see SecurityManager#checkPermission
* @see RuntimePermission
* @see Throwable#getStackTrace
*
* @since 1.5
*/
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
// check for getStackTrace permission
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(
SecurityConstants.GET_STACK_TRACE_PERMISSION);
security.checkPermission(
SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
}
// Get a snapshot of the list of all threads
Thread[] threads = getThreads();
StackTraceElement[][] traces = dumpThreads(threads);
Map<Thread, StackTraceElement[]> m = new HashMap<>(threads.length);
for (int i = 0; i < threads.length; i++) {
StackTraceElement[] stackTrace = traces[i];
if (stackTrace != null) {
m.put(threads[i], stackTrace);
}
// else terminated so we don't put it in the map
}
return m;
}
private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION =
new RuntimePermission("enableContextClassLoaderOverride");
/** cache of subclass security audit results */
/* Replace with ConcurrentReferenceHashMap when/if it appears in a future
* release */
private static class Caches {
/** cache of subclass security audit results */
static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits =
new ConcurrentHashMap<>();
/** queue for WeakReferences to audited subclasses */
static final ReferenceQueue<Class<?>> subclassAuditsQueue =
new ReferenceQueue<>();
}
/**
* Verifies that this (possibly subclass) instance can be constructed
* without violating security constraints: the subclass must not override
* security-sensitive non-final methods, or else the
* "enableContextClassLoaderOverride" RuntimePermission is checked.
*/
private static boolean isCCLOverridden(Class<?> cl) {
if (cl == Thread.class)
return false;
processQueue(Caches.subclassAuditsQueue, Caches.subclassAudits);
WeakClassKey key = new WeakClassKey(cl, Caches.subclassAuditsQueue);
Boolean result = Caches.subclassAudits.get(key);
if (result == null) {
result = Boolean.valueOf(auditSubclass(cl));
Caches.subclassAudits.putIfAbsent(key, result);
}
return result.booleanValue();
}
/**
* Performs reflective checks on given subclass to verify that it doesn't
* override security-sensitive non-final methods. Returns true if the
* subclass overrides any of the methods, false otherwise.
*/
private static boolean auditSubclass(final Class<?> subcl) {
Boolean result = AccessController.doPrivileged(
new PrivilegedAction<Boolean>() {
public Boolean run() {
for (Class<?> cl = subcl;
cl != Thread.class;
cl = cl.getSuperclass())
{
try {
cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
try {
Class<?>[] params = {ClassLoader.class};
cl.getDeclaredMethod("setContextClassLoader", params);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
}
return Boolean.FALSE;
}
}
);
return result.booleanValue();
}
private native static StackTraceElement[][] dumpThreads(Thread[] threads);
private native static Thread[] getThreads();
public long getId() {
return tid;
}
public enum State {
// Thread state for a thread which has not yet started
NEW,
// Thread state for a runnable thread
RUNNABLE,
// Thread state for a thread blocked waiting for a monitor lock
BLOCKED,
// Thread state for a waiting thread
WAITING,
//Thread state for a waiting thread with a specified waiting time.
TIMED_WAITING,
Thread state for a terminated thread.
TERMINATED;
}
//Returns the state of this thread.
public State getState() {
// get current thread state
return sun.misc.VM.toThreadState(threadStatus);
}
// Added in JSR-166
//函数式接口
@FunctionalInterface
public interface UncaughtExceptionHandler {
/**
* Method invoked when the given thread terminates due to the
* given uncaught exception.
* <p>Any exception thrown by this method will be ignored by the
* Java Virtual Machine.
* @param t the thread
* @param e the exception
*/
void uncaughtException(Thread t, Throwable e);
}
// null unless explicitly set
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
// null unless explicitly set
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
//设置当线程由于未捕获的异常而突然终止时调用的默认处理程序,
//并且没有为该线程定义其他处理程序。
//未捕获的异常处理首先由线程控制,然后由线程的ThreadGroup对象控制,
//最后由默认的未捕获异常处理程序控制。如果线程没有明确的未捕获异常处理程序集,
//并且线程的线程组(包括父线程组)不专门化其uncaughtException方法,
//则将调用默认处理程序的uncaughtException方法。
//通过设置默认的未捕获异常处理程序,应用程序可以更改已经接受任何“默认”的线程的未捕获异常的处
//理方式(例如,记录到特定设备或文件)。系统提供的行为。请注意,默认的未捕获异常处理程序通常
//不应该遵循线程的ThreadGroup对象,因为这可能导致无限递归。
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(
new RuntimePermission("setDefaultUncaughtExceptionHandler")
);
}
defaultUncaughtExceptionHandler = eh;
}
public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
return defaultUncaughtExceptionHandler;
}
//the uncaught exception handler for this thread
public UncaughtExceptionHandler getUncaughtExceptionHandler() {
return uncaughtExceptionHandler != null ?
uncaughtExceptionHandler : group;
}
//设置当此线程由于未捕获的异常而突然终止时调用的处理程序
public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
checkAccess();
uncaughtExceptionHandler = eh;
}
//向处理程序发送未捕获的异常.
private void dispatchUncaughtException(Throwable e) {
getUncaughtExceptionHandler().uncaughtException(this, e);
}
//从指定的映射中删除已在指定引用队列中排队的任何键。
static void processQueue(ReferenceQueue<Class<?>> queue,
ConcurrentMap<? extends
WeakReference<Class<?>>, ?> map)
{
Reference<? extends Class<?>> ref;
while((ref = queue.poll()) != null) {
map.remove(ref);
}
}
//Weak key for Class objects 作为ThreadLocal中弱引用
static class WeakClassKey extends WeakReference<Class<?>> {
//saved value of the referent's identity hash code
private final int hash;
//Create a new WeakClassKey to the given object, registered with a queue.
WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
super(cl, refQueue);
hash = System.identityHashCode(cl);
}
//Returns the identity hash code of the original referent.
@Override
public int hashCode() {
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == this)
return true;
if (obj instanceof WeakClassKey) {
Object referent = get();
return (referent != null) &&
(referent == ((WeakClassKey) obj).get());
} else {
return false;
}
}
}
//以下三个最初未初始化的字段由类java.util.concurrent.ThreadLocalRandom独占管理。
//这些字段用于在并发代码中构建高性能PRNG,并且我们不会冒险意外错误共享。
//因此,字段与@Contended隔离。
/** The current seed for a ThreadLocalRandom */
@sun.misc.Contended("tlr")
long threadLocalRandomSeed;
/** Probe hash value; nonzero if threadLocalRandomSeed initialized */
@sun.misc.Contended("tlr")
int threadLocalRandomProbe;
/** Secondary seed isolated from public ThreadLocalRandom sequence */
@sun.misc.Contended("tlr")
int threadLocalRandomSecondarySeed;
/* Some private helper methods */
private native void setPriority0(int newPriority);
private native void stop0(Object o);
private native void suspend0();
private native void resume0();
private native void interrupt0();
private native void setNativeName(String name);
}
最后
以上就是怕黑向日葵为你收集整理的java基础-7-A -线程-Thread类解析的全部内容,希望文章能够帮你解决java基础-7-A -线程-Thread类解析所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复