zoukankan      html  css  js  c++  java
  • 多线程源码--Thread源码

    前言

      Java.lang.Thread是Java应用程序员对Java多线程的第一站,Thread就是对Java线程本身的抽象

      所以在Java中的线程编程概念中,一个Thread实例 == 一个线程
      线程有哪些属性、行为,Thread大致就有哪些属性、行为。

    源码

    构造器

      

    public Thread() { init(null, null, "Thread-" + nextThreadNum(), 0); }
    public Thread(Runnable target) { init(null, target, "Thread-" + nextThreadNum(), 0); }
    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(Runnable target, AccessControlContext acc) { init(null, target, "Thread-" + nextThreadNum(), 0, acc, false); }

    从上面可以看出,所有的构造器都依赖着init方法

      private void init(ThreadGroup g, Runnable target, String name,long stackSize)

    除了上面列表的最后一个构造器外,其他构造器传递的参数,都在上面 init() 方法参数只能。这几个参数的解释如下:

    ThreadGroup 线程组;

    Runnable 封装线程任务;

    String name 线程名称;

    long stackSize 虚拟机栈的空间大小,默认为0,不设置 即忽略它。

    现在来说说与构造器相关的 init() 方法源码

     

    由上图可见,大多数构造器(就是除上面最后一个),都是先将数据传递上图第一个init方法,然后内部再次调用它的重载方法。我们来看看这个方法源码

    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(); //父线程,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;
    
            //设置线程ID
            tid = nextThreadID();
        }

    属性

        private volatile String name; //线程名称
        private int            priority; //线程优先级
        private Thread         threadQ; 
        private long           eetop; 
        //是否单步执行这个线程。
        private boolean     single_step;
        //是否为守护线程
        private boolean     daemon = false;
        //jvm状态值
        private boolean     stillborn = false;
        //线程任务
        private Runnable target;
        //线程组
        private ThreadGroup group;
        //此线程的上下文类装入器
        private ClassLoader contextClassLoader;
        //它封装的上下文做出系统资源访问决策。
        private AccessControlContext inheritedAccessControlContext;
    
        //自动编号。就是当没有设置线程名称的时候。我们看到的Thread-0 Thread-1
        private static int threadInitNumber;
        private long stackSize; //线程堆栈空间大小,默认0,不用管
    
        //jvm私有状态,在本机线程终止后仍然存在。
        private long nativeParkEventPointer;
        private long tid; //线程ID
    
        //用于生成线程ID
        private static long threadSeqNumber;
        private volatile int threadStatus = 0;//线程初始状态。表示线程尚未启动
        volatile Object parkBlocker;
        private volatile Interruptible blocker;
        private final Object blockerLock = new Object();//用于synchronized关键字的实例锁
        public final static int MIN_PRIORITY = 1;//最小优先级
        public final static int NORM_PRIORITY = 5;//默认优先级
        public final static int MAX_PRIORITY = 10;//最大优先级

    常用的关键方法

    start()启动方法

    public synchronized void start() {
            //零状态值对应于状态“NEW”。
            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) {
                    //什么也不做。如果start0抛出一个投掷物它将被传递到调用堆栈
                }
            }
        }
    private native void start0(); //start0本地方法

    run()运行方法

    public void run() {
         //线程任务不为空时,调用父接口的run方法
    if (target != null) { target.run(); } }

    exit()退出方法

    //清除必要的资源
    private
    void exit() { if (group != null) { group.threadTerminated(this); group = null; } target = null; threadLocals = null; inheritableThreadLocals = null; inheritedAccessControlContext = null; blocker = null; uncaughtExceptionHandler = null; }

    interrupt()中断方法

    public void interrupt() {
            if (this != Thread.currentThread())
                checkAccess();//权限检查
            synchronized (blockerLock) {
                Interruptible b = blocker; //设置中断接口
                if (b != null) {
                    interrupt0(); // 设置中断标志
                    b.interrupt(this);
                    return;
                }
            }
            interrupt0();
        }
    //interrupt0()是本地方法

    interrupted() 是否已中断

    public static boolean interrupted() {
            return currentThread().isInterrupted(true);
        }
    public boolean isInterrupted() {
            return isInterrupted(false);
        }
    private native boolean isInterrupted(boolean ClearInterrupted);

    线程是否被激活isAlive()

    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 static native void yield();  //暂停一下线程,回到就绪状态


    join()方法

    public final void join() throws InterruptedException {
            join(0); //调用下面的方法
        } 
    public final synchronized void join(long millis) throws InterruptedException {
            long base = System.currentTimeMillis(); //设置开始时间
            long now = 0;
            if (millis < 0) {  //传递参数小于0,抛异常
                throw new IllegalArgumentException("timeout value is negative");
            }
         //参数为0
    if (millis == 0) { while (isAlive()) { //线程处于运行状态 wait(0); //调用Object的wait方法 } } else { //如果参数大于0 while (isAlive()) { long delay = millis - now; if (delay <= 0) { //当前时间不能大于设置的时间之后的时间 break; } wait(delay); //调用Object的wait方法 now = System.currentTimeMillis() - base; //当前时间 } } } public final synchronized void join(long millis, int nanos) throws InterruptedException { if (millis < 0) { //不可小于0 throw new IllegalArgumentException("timeout value is negative"); } if (nanos < 0 || nanos > 999999) { //纳秒不可超过规定范围 throw new IllegalArgumentException( "nanosecond timeout value out of range"); }      //如果纳秒符合条件,秒自增1 if (nanos >= 500000 || (nanos != 0 && millis == 0)) { millis++; } join(millis); //调用上面的方法 }

    sleep()方法

    public static void sleep(long millis, int nanos) throws InterruptedException {
            if (millis < 0) { //参数必须大于0
                throw new IllegalArgumentException("timeout value is negative");
            }
            if (nanos < 0 || nanos > 999999) { //纳秒要在规定范围
                throw new IllegalArgumentException(
                                    "nanosecond timeout value out of range");
            }
         //如果纳秒符合条件,秒自增1
    if (nanos >= 500000 || (nanos != 0 && millis == 0)) { millis++; } sleep(millis); //调用本地方法 }
    public static native void sleep(long millis) throws InterruptedException;  //本地方法

    Daemon相关方法

    public final void setDaemon(boolean on) {  //设置是否为守护线程
            checkAccess(); //权限效验
            if (isAlive()) {  //当前线程不能为激活状态
                throw new IllegalThreadStateException();
            }
            daemon = on;  //设置当前线程是否为守护线程
        }
    //是否为守护线程
    public final boolean isDaemon() { return daemon; }

    以上就是常用的api源码,个人能力不足,还请见谅,待之后进行完善。

  • 相关阅读:
    AJAX删除事件与加载数据
    AJAX的基本操作
    用JavaScript写弹窗
    jQuery事件和JSON点语法
    jQuery
    jQuery基础知识
    php 实现简单购物车功能(2)
    css实现3D立方体旋转特效
    for循环与foreach的区别
    微信小程序开发2 双线程模型,小程序中app.js中的生命周期,小程序的页面的生命周期,小程序的事件,事件补充(事件的冒泡,捕获)
  • 原文地址:https://www.cnblogs.com/FondWang/p/12099004.html
Copyright © 2011-2022 走看看