Java Thread类源码详解

概述

Java所有多线程的实现,均通过封装Thread类实现,所以深入Thread类,对深入理解java多线程很有必要


构造函数:
  • Thread的构造函数,采用缺省的方式实现:
//传入Runnable接口实现
Thread(Runnable target)
//传入Runnable接口实现,传入线程名
Thread(Runnable target, String name) 
//设置当前线程用户组
Thread(ThreadGroup group, Runnable target)
//设置用户组,传入线程名
Thread(ThreadGroup group, Runnable target, String name)
//设置用户组,传入线程名,设置当前线程栈大小
Thread(ThreadGroup group, Runnable target, String name, long stackSize) 
  • Thread类构造函数源码分析:
    1.线程默认名称生产规则:
// 当前缺省线程名:"Thread-" + nextThreadNum()
public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
---
// nextThreadNum 同步方法,线程安全,不会出现重复的threadInitNumber
private static int threadInitNumber;
private static synchronized int nextThreadNum() {
    return threadInitNumber++;
}

2.线程私有化实现

/**
     * Initializes a Thread.
     *
     * @param g the Thread group
     * @param target the object whose run() method gets called
     * @param name the name of the new Thread
     * @param stackSize the desired stack size for the new thread, or
     *        zero to indicate that this parameter is to be ignored.
     * @param acc the AccessControlContext to inherit, or
     *            AccessController.getContext() if null
     * @param inheritThreadLocals if {@code true}, inherit initial values for
     *            inheritable thread-locals from the constructing thread
     */
    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;
        /* 设置当前线程是否为守护线程,默认是和当前类的ThreadGroup设置相
        * 同。如果是守护线程的话,当前线程结束会随着主线程的退出而退出。
        *jvm退出的标识是,当前系统没有活跃的非守护线程。
        */
        this.daemon = parent.isDaemon();
        /*设置的线程的访问权限默认为当前ThreadGroup权限*/
        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 */
        /*设置指定的栈大小,如果未指定大小,将在jvm 初始化参数中声明:Xss参数进行指定*/
        this.stackSize = stackSize;

        /* Set thread ID */
        tid = nextThreadID();
    }

start()方法源码分析:
/*  导致此线程开始执行; Java Virtual Machine调用此线程的run方法。
    结果是两个线程同时运行:当前线程(从调用返回到start方法)和另一个线程(执行其run方法)。
    不止一次启动线程永远不合法。
    特别是,一旦完成执行,线程可能无法重新启动。
    @exception IllegalThreadStateException如果线程已经启动。
    @see #run()
    @see #stop()*/

 public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        //此判断当前线程只能被启动一次,不能被重复启动
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        /*通知组该线程即将启动
          *这样它就可以添加到组的线程列表中
         *并且该组的未启动计数可以递减。*/
        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 */
            }
        }
    }

join() 方法源码分析:
/**
     * Waits at most {@code millis} milliseconds for this thread to
     * die. A timeout of {@code 0} means to wait forever.
     *
     * <p> This implementation uses a loop of {@code this.wait} calls
     * conditioned on {@code this.isAlive}. As a thread terminates the
     * {@code this.notifyAll} method is invoked. It is recommended that
     * applications not use {@code wait}, {@code notify}, or
     * {@code notifyAll} on {@code Thread} instances.
     *
     * @param  millis
     *         the time to wait in milliseconds
     *
     * @throws  IllegalArgumentException
     *          if the value of {@code millis} is negative
     *
     * @throws  InterruptedException
     *          if any thread has interrupted the current thread. The
     *          <i>interrupted status</i> of the current thread is
     *          cleared when this exception is thrown.
     */
    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) {
        // 如果millis == 0 线程将一直等待下去
            while (isAlive()) {
                wait(0);
            }
        } else {
            // 指定了millis ,等待指定时间以后,会break当前线程
            while (isAlive()) {
                long delay = millis - now;
                if (delay <= 0) {
                    break;
                }
                wait(delay);
                now = System.currentTimeMillis() - base;
            }
        }
    }

Thread 内部枚举 State:
public enum State {
        /**
         * Thread state for a thread which has not yet started.
         * 尚未启动的线程的线程状态
         */
        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.
         * 可运行线程的线程状态。 runnable中的一个线程
         * state正在Java虚拟机中执行但它可能正在执行
         * 等待操作系统中的其他资源
         * 如处理器。
         */
        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}.
         * 线程阻塞等待监视器锁定的线程状态。(获取系统锁)
         * 处于阻塞状态的线程正在等待监视器锁定
         * 输入同步块/方法或
         * 调用后重新输入同步块/方法
         */
        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,

        /**
         * 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>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

线程六种状态之间的关系,其中进入阻塞状态是java虚拟机自定义状态,通常都是遇到获取当前锁,synchronize代码同步块

image


run()方法源码:
/*Thread类重写了Runnable接口的run()方法。
 该run()方法首先判断当前是否有Runnable的实现target存在。
 如果存在就执行target.run()
*/
 @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

run 方法的实现,是通过Java静态代理的方式实现的。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lm7AJmJe-1577089548842)(http://i.imgur.com/oh3VMNs.gif)]


  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
Java中的线程是通过Thread来实现的,Thread封装了所有线程相关的方法和属性。下面是Thread的部分源码: ```java public class Thread implements Runnable { //线程状态 private volatile int threadStatus = 0; private static final int RUNNING = 1; private static final int SHUTDOWN = -1; private static final int STOP = -2; private static final int TIDYING = 2; private static final int TERMINATED = 3; //线程优先级 public final static int MIN_PRIORITY = 1; public final static int NORM_PRIORITY = 5; public final static int MAX_PRIORITY = 10; //线程组 private ThreadGroup group; private Runnable target; private String name; private long stackSize; private long eetop; //线程ID private long tid; //线程本地存储 ThreadLocal.ThreadLocalMap threadLocals = null; ThreadLocal.ThreadLocalMap inheritableThreadLocals = null; //线程中断标志 private volatile boolean interrupted = false; private static final int HIBERNATE = 0; private static final int WAITING = 1; private static final int TIMED_WAITING = 2; private static final int BLOCKED = 3; private static final int NEW = 0; //线程锁 private Object parkBlocker; //线程中断处理 private void handleInterrupt() { if (this != Thread.currentThread()) throw new RuntimeException("Only the original thread can be interrupted"); if (this.interrupted) { park(); } } //线程休眠 public static void sleep(long millis) throws InterruptedException { Thread.sleep(millis, 0); } //中断线程 public void interrupt() { if (this != Thread.currentThread()) checkAccess(); synchronized (this) { interrupted = true; notifyAll(); } } //线程运行方法 @Override public void run() { if (target != null) { target.run(); } } } ``` 在Thread中,我们可以看到一些重要的属性和方法,比如: - threadStatus: 线程状态,用整数表示,包含RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED五种状态。 - group: 线程所属的线程组。 - target: 线程要执行的任务。 - name: 线程名称。 - stackSize: 线程堆栈大小。 - tid: 线程ID。 - threadLocals: 线程本地存储。 - interrupted: 线程中断标志。 - parkBlocker: 线程锁。 - sleep(): 线程休眠方法。 - interrupt(): 中断线程方法。 - run(): 线程运行方法。 通过这些属性和方法,我们可以使用Java中的线程实现多线程编程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值