JDK1.8源码阅读(4)--Long/Short/Thread

JDK1.8源码阅读(4)–Long/Short/Thread

一.Long类

类图:在这里插入图片描述
Long类继承于Number抽象类和接口Comparable
Long有些变量和方法跟Integer中类似,就不再赘述。

二.Short类

类图:在这里插入图片描述
Short类继承于Number抽象类和接口Comparable
Short有些变量和方法跟Integer中类似,就不再赘述。

三.Thread类

类图:
在这里插入图片描述
首先是一个定义函数式编程的FunctionalInterface注释特点:
1.唯一的抽象方法,有且仅有一个
2.可用于lamba类型的使用方式
3.不能被覆盖之后,再声明为抽象方法,则不算抽象方法。例如接口实现了Object中的方法。
4.加上标注,则会触发JavaCompiler的检查。对于符合函数接口的接口,加不加都无关紧要,但是加上则会提供一层编译检查的保障。如果不符合,则会报错。
接下来是接口Runnable:
里面只有一个抽象方法:public abstract void run(); 由于是FunctionalInterface修饰因此可以直接使用函数式编程
最后分析下Thread类:
static {
registerNatives();
}
静态代码块,再类初始化的时候就会运行,registerNatives方法:当该类被加载的时候,调用该方法完成对该类中本地方法的注册。
private volatile char name[]; 线程名称
private int priority; 线程优先级
private Thread threadQ; 线程
private long eetop; JVM中的JavaThread指针
private boolean single_step; 这个线程是否是单步的
private boolean daemon = false; 这个线程是否是个伴随线程
private boolean stillborn = false; JVM设置的参数
private Runnable target; 用来引用构造函数中传递的Runnable参数,表示线程执行的代码
private ThreadGroup group; 当前线程所处的线程组
private ClassLoader contextClassLoader; 所处的类加载器
private AccessControlContext inheritedAccessControlContext; 此线程继承的AccessControlContext
private static int threadInitNumber; 线程的初始名称,如果没有命名,会自动以thread-T命名
private static synchronized int nextThreadNum() 加锁地获得下个线程命名
ThreadLocal.ThreadLocalMap threadLocals = null; 线程局部缓存,这是一个键值对组合,为当前线程关联一些“独享”变量,ThreadLocal是key。
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; 从父线程继承而来的线程局部缓存,由InheritableThreadLocal维护
private long stackSize; 线程请求的堆栈大小。
private long nativeParkEventPointer; JVM设置的参数
private long tid; 线程ID
private static long threadSeqNumber; 计数变量,用在nextThreadID方法中为线程生成ID
private volatile int threadStatus = 0; 线程状态 初始化时是0,意味着线程尚未开始
private static synchronized long nextThreadID() 加锁的获得下个线程ID
volatile Object parkBlocker; 用于LockSupport.park(Object)方法中,用于引用该方法参数
private volatile Interruptible blocker; 线程在执行可中断IO操作时阻塞该线程的对象,线程的中断状态被设置后blocker的interrupt方法会被调用。
private final Object blockerLock = new Object(); 设置上述blocker变量时用的锁

    void blockedOn(Interruptible b) {
        synchronized (blockerLock) {
            blocker = b;
        }
    }

调用blockedOn方法给blocker赋值。
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) 睡眠时间精确到纳秒,但是其实底层还是将纳秒四舍五入成毫秒后处理
private void init(ThreadGroup g, Runnable target, String name,long stackSize, AccessControlContext acc)
init方法,其实就是构造函数中调用的方法,参数包括了线程组,线程执行的代码,线程名称,给线程分配的堆栈深度,是否具有权限

    private void init(ThreadGroup g, Runnable target, String name,
                      long stackSize, AccessControlContext acc) {
                      //当名称为null时,会抛出错误
        if (name == null) {
            throw new NullPointerException("name cannot be null");
        }
		//把name转成字节数组后存入成员变量
        this.name = name.toCharArray();
		//将线程的父线程设置为当前正在运行的线程
        Thread parent = currentThread();
        //将线程的安全性设置成跟系统一样
        SecurityManager security = System.getSecurityManager();
        //如果创建时输入的线程组为null但是线程安全性不为null,就把线程所属的线程组设置为安全管理器的线程组
        if (g == null) {
            /* Determine if it's an applet or not */

            /* If there is a security manager, ask the security manager
            /* <p>
            /* 
               what to do. */
            if (security != null) {
                g = security.getThreadGroup();
            }

            /* If the security doesn't have a strong opinion of the matter
            /* <p>
            /* 
               use the parent thread group. */
               //如果安全管理器的安全组也为空,就把线程组设置为跟父线程的线程组一致
            if (g == null) {
                g = parent.getThreadGroup();
            }
        }

        /* checkAccess regardless of whether or not threadgroup is
        /* <p>
        /* 
           explicitly passed in. */
           //判断下当前所属线程组是否具有可访问性
        g.checkAccess();

        /*
         * Do we have the required permissions?
         * <p>
         *  我们有所需的权限吗?
         * 
         */
         获得许可证
        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);
        如果父线程的线程局部缓存不为null,那么继承
        if (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 */
        设置线程ID
        tid = nextThreadID();
    }

protected Object clone() 重写Object方法,但是这个重写是为了不让Thread类调用clone方法,如果调用将会抛出错误。

public Thread()
无参构造函数,线程名称将会自动命名

    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }

public Thread(Runnable target)指定了线程将要执行的任务

Thread(Runnable target, AccessControlContext acc) 指定了线程要执行的任务以及是否具有权限

public Thread(ThreadGroup group, Runnable target) 指定了线程组以及要执行的任务

public Thread(String name) 指定了线程名称

public Thread(ThreadGroup group, String name) 指定了线程组以及线程名称

public Thread(Runnable target, String name) 指定了线程要执行的任务以及线程名称

public Thread(ThreadGroup group, Runnable target, String name) 指定了线程的线程组、线程要执行的任务以及线程名称

public Thread(ThreadGroup group, Runnable target, String name,long stackSize) 指定了线程的线程组、线程要执行的任务,线程名称以及给线程安排的堆栈大小。

public synchronized void start() 开始运行线程,线程将进入就绪队列

    public synchronized void start() {
    //如果当前线程不是初始状态却调用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
                /* <p>
                /* 
                  it will be passed up the call stack */
            }
        }
    }

public void run() 重写了Runnable接口的run方法,注意的是Thread类中定义了如果参数target不是Null那么将会调用target的run方法,只有为null时才会调用自身的run方法。

    public void run() {
        if (target != null) {
            target.run();
        }
    }

private void exit() 一个私有方法,这个方法被系统调用,给Thread一个机会在它实际退出之前退出。

@Deprecated
public final void stop() 停止线程,但是已经被建议停止使用。 主要是因为调用这个方法停止线程并不会释放锁等资源。

   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
        //VM会帮忙停止这个线程
        stop0(new ThreadDeath());
    }

public void interrupt() 中断线程,只是给线程预设一个标记,并不是让线程立刻停下来

    public void interrupt() {
    //如果调用调用方法的线程不是当前运行的线程需要验证权限
        if (this != Thread.currentThread())
            checkAccess();
		//如果当前blocker中有值,将会调用值中的interrupt方法,在调用interrupt方法前会把中断标志位修改。
        synchronized (blockerLock) {
            Interruptible b = blocker;
            if (b != null) {
                interrupt0();           // Just to set the interrupt flag
                b.interrupt(this);
                return;
            }
        }
        interrupt0();
    }

public static boolean interrupted()
这里需要注意的是其中返回的中断位信息其实是当前线程的,并且会把当前线程的标志位清空。

    public static boolean interrupted() {
        return currentThread().isInterrupted(true);
    }

public boolean isInterrupted()
返回的是调用这个方法的对象的中断位信息,并且不会清空线程中断标志位。

private native boolean isInterrupted(boolean ClearInterrupted) 本地方法

@Deprecated
public void destroy() 这方法已经不能使用,使用会抛出错误。

public final native boolean isAlive() 本地方法,返回调用这个方法的线程是否存活。

@Deprecated
public final void suspend() 暂停线程,已经不推荐使用
不会释放锁

    @Deprecated
    public final void suspend() {
        checkAccess();
        suspend0();
    }

@Deprecated
public final void resume() 恢复线程,已经不推荐使用

public final void setPriority(int newPriority) 设置线程的优先级

    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() 得到线程的优先级值

public final synchronized void setName(String name) 加锁的设置线程的名称

    public final synchronized void setName(String name) {
        checkAccess();
        this.name = name.toCharArray();
        if (threadStatus != 0) {
            setNativeName(name);
        }
    }

public final String getName() 得到当前线程的名称

public final ThreadGroup getThreadGroup() 返回当前线程所属的线程组

public static int activeCount() 返回当前线程组存活的线程数量

public static int enumerate(Thread tarray[]) 递归获取当前线程所在线程组的所有线程

@Deprecated
public native int countStackFrames() 不推荐使用的本地方法,返回堆栈深度

public final synchronized void join(long millis)throws InterruptedException 会阻塞当前线程,先运行当前对象的线程,此过程需要加锁

    public final synchronized void join(long millis)
    throws InterruptedException {
    //base是开始时间
        long base = System.currentTimeMillis();
        long now = 0;
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }
        当设置millis是0的时候默认只要当前线程存活就把加入等待队列
        if (millis == 0) {
            while (isAlive()) {
                wait(0);
            }
        } else {
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                当前线程阻塞delay秒后返回
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

public final synchronized void join(long millis, int nanos) throws InterruptedException 可以指定纳秒

public final void join() throws InterruptedException 默认join(0)

public static void dumpStack() 生成一个异常栈信息

public final void setDaemon(boolean on) 设置线程是否是伴随线程,需要主要是当线程存活的状态时不可以调用

public final boolean isDaemon() 返回线程是否是伴随线程

public final void checkAccess() 检查是否具有权限

public String toString() 重写object的toString方法

    public String toString() {
        ThreadGroup group = getThreadGroup();
        if (group != null) {
            return "Thread[" + getName() + "," + getPriority() + "," +
                           group.getName() + "]";
        } else {
            return "Thread[" + getName() + "," + getPriority() + "," +
                            "" + "]";
        }
    }

@CallerSensitive
public ClassLoader getContextClassLoader() 用CallerSensitive注解的获取当前线程上下文类加载器的方法。

public void setContextClassLoader(ClassLoader cl) 设置线程的上下文类加载器

public static native boolean holdsLock(Object obj) 本地方法,判断当前线程是否具有对象obj的锁

private static final StackTraceElement[] EMPTY_STACK_TRACE= new StackTraceElement[0]; 空栈帧

public StackTraceElement[] getStackTrace() 当前线程中的栈帧

public static Map<Thread, StackTraceElement[]> getAllStackTraces() 获得目前所有正在运行的线程的栈帧

private native static StackTraceElement[][] dumpThreads(Thread[] threads); 线程的栈帧信息

private native static Thread[] getThreads(); 当前运行的所有线程

public long getId() 返回线程的tid

public enum State 枚举类线程状态

    public enum State {
    //初始化
        NEW,
//正在运行
        RUNNABLE,
        //阻塞
        BLOCKED,
//等待
        WAITING,
     //超时等待   
        TIMED_WAITING,
//终止
        TERMINATED;
    }

public State getState() 返回对象线程的状态

public boolean equals(Object obj)

        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;
            }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值