Thread

一、源码

1、注册本地方法

private static native void registerNatives();
static {
    registerNatives();
}

Java有两种方法:Java方法和本地方法。Java方法是由Java语言编写,编译成字节码,存储在class文件中。本地方法是由其他语言(比如C,C++,或者汇编)编写的,编译成和处理器相关的机器代码。本地方法保存在动态连接库中,格式是各个平台专有的。Java方法是平台无关的,单本地方法却不是。运行中的Java程序调用本地方法时,虚拟机装载包含这个本地方法的动态库,并调用这个方法。本地方法是联系Java程序和底层主机操作系统的连接方法

registerNatives()方法的作用就是注册除了registerNatives()以外的其他本地方法

 

2、属性

private volatile String name;

线程名称,volatile保证变量可见性

private int priority;

线程优先级

private boolean daemon = false;

默认不是守护线程

private Runnable target;

可执行的runnable

private ThreadGroup group;

当前线程的分组

private ClassLoader contextClassLoader;

thread的类加载器,方便有需要的父类加载器调用子类加载器,完成类的加载

private static int threadInitNumber;
private static synchronized int nextThreadNum() {
    return threadInitNumber++;
}

默认的线程名称编号,全局唯一并递增,在没有指定线程名称时会被使用

ThreadLocal.ThreadLocalMap threadLocals = null;
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;

线程的本地副本、线程父类的本地副本

private long stackSize;

可以手动设置线程的栈深度,默认0,有些虚拟机不支持

private long tid;
private static long threadSeqNumber;
private static synchronized long nextThreadID() {
    return ++threadSeqNumber;
}

线程的id,全局唯一并递增,编号大于等于threadInitNumber

volatile Object parkBlocker

是给LockSupport使用的,控制线程阻塞

private volatile Interruptible blocker;
private final Object blockerLock = new Object();
void blockedOn(Interruptible b) {
    synchronized (blockerLock) {
        blocker = b;     
    }
}

blocker和blockerLock用于控制线程中断,blockedOn是给nio对blocker赋值用的

public final static int MIN_PRIORITY = 1;
public final static int NORM_PRIORITY = 5;
public final static int MAX_PRIORITY = 10;

线程的优先级常量

 

3、构造方法

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);
}

各种构造方法

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;

    //从本地方法获得当前线程作为parent
    Thread parent = currentThread();

    //安全管理器相关
    SecurityManager security = System.getSecurityManager();
    if (g == null) {

        if (security != null) {
            g = security.getThreadGroup();
        }

        if (g == null) {
            g = parent.getThreadGroup();
        }
    }
    g.checkAccess();
    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);

    this.stackSize = stackSize;

    tid = nextThreadID();
}

初始化线程的方法

 

4、一般方法

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);
}

使线程睡眠指定的时间,增加了一个纳秒,如果大于500微秒(500000纳秒),就增加1毫秒,是一个四舍五入的近似运算

@Override
protected Object clone() throws CloneNotSupportedException {
    throw new CloneNotSupportedException();
}

不支持克隆

public synchronized void start() {

    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 */
        }
    }
}
private native void start0();

启动线程,如果线程已经启动就不能启动了,如果启动失败就通知线程组启动失败

@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;
}

终止线程 

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();
}
public static boolean interrupted() {
    return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
    return isInterrupted(false);
}
private native boolean isInterrupted(boolean ClearInterrupted);

中断线程,暂时还不理解,后面补充

public final native boolean isAlive();

本地方法,线程是否存活

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;
}

设置优先级,获得优先级

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);
}

将线程组的线程复制到数组中

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;
        }
    }
}
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);
}
public final void join() throws InterruptedException {
    join(0);
}

等待当前线程结束,当线程不再存活时,再执行调用join方法的进程

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;
}

设置为守护进程

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() + "," +
                        "" + "]";
    }
}

输出tostring

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;
}

获得和设置thread的类加载器

public static native boolean holdsLock(Object obj);

判断当前线程是否持有某个对象的锁

private static final StackTraceElement[] EMPTY_STACK_TRACE = new StackTraceElement[0];
public StackTraceElement[] getStackTrace() {
    if (this != Thread.currentThread()) {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(
                SecurityConstants.GET_STACK_TRACE_PERMISSION);
        }
        if (!isAlive()) {
            return EMPTY_STACK_TRACE;
        }
        StackTraceElement[][] stackTraceArray = dumpThreads(new Thread[] {this});
        StackTraceElement[] stackTrace = stackTraceArray[0];
        if (stackTrace == null) {
            stackTrace = EMPTY_STACK_TRACE;
        }
        return stackTrace;
    } else {
        return (new Exception()).getStackTrace();
    }
}
private native static StackTraceElement[][] dumpThreads(Thread[] threads);
private native static Thread[] getThreads();

返回表示此线程的堆栈转储的堆栈跟踪元素数组

private static final RuntimePermission SUBCLASS_IMPLEMENTATION_PERMISSION = new RuntimePermission("enableContextClassLoaderOverride");

当enableContextClassLoaderOverride被开启时,checkPermission将被重写子类直接或间接地调用

private static class Caches {
    static final ConcurrentMap<WeakClassKey,Boolean> subclassAudits = new ConcurrentHashMap<>();
    static final ReferenceQueue<Class<?>> subclassAuditsQueue = new ReferenceQueue<>();
}

subclassAudits保存子类的代码执行安全性检测结果,subclassAuditsQueue保存已审核过的子类弱引用

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();
}
private static boolean auditSubclass(final Class<?> subcl) {
    Boolean result = AccessController.doPrivileged(
        new PrivilegedAction() {
            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();
}
static void processQueue(ReferenceQueue<Class<?>> queue, ConcurrentMap<? extends WeakReference<Class<?>>, ?> map)
{
    Reference<? extends Class<?>> ref;
    while((ref = queue.poll()) != null) {
        map.remove(ref);
    }
}
static class WeakClassKey extends WeakReference<Class<?>> {

    private final int hash;

    WeakClassKey(Class<?> cl, ReferenceQueue<Class<?>> refQueue) {
        super(cl, refQueue);
        hash = System.identityHashCode(cl);
    }

    @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;
        }
    }
}

安全相关

public enum State {
    NEW,
    RUNNABLE,
    BLOCKED,
    WAITING,
    TIMED_WAITING,
    TERMINATED;
}
public State getState() {
    return sun.misc.VM.toThreadState(threadStatus);
}

获得线程的状态

public interface UncaughtExceptionHandler {
    void uncaughtException(Thread t, Throwable e);
}
private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
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;
}
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);
}

异常处理相关,jvm会调用线程的getUncaughtExceptionHandler来处理未捕获的异常,这个异常实现Thread.UncaughtExceptionHandler接口,以下是ThreadGroup的实现

public void uncaughtException(Thread t, Throwable e) {
    if (parent != null) {
        parent.uncaughtException(t, e);
    } else {
        Thread.UncaughtExceptionHandler ueh = Thread.getDefaultUncaughtExceptionHandler();
        if (ueh != null) {
            ueh.uncaughtException(t, e);
        } else if (!(e instanceof ThreadDeath)) {
            System.err.print("Exception in thread \"" + t.getName() + "\" ");
            e.printStackTrace(System.err);
        }
    }
}

优先调用当前线程的异常handler,没有的话调用全局的默认异常handler,如果还没有就执行e.printStackTrace

long threadLocalRandomSeed;
int threadLocalRandomProbe;
int threadLocalRandomSecondarySeed;

给ThreadLocalRandom使用的属性

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);

一些私有的本地方法

 

posted @ 2020-01-28 10:47  syxsdhy  阅读(296)  评论(0编辑  收藏  举报