Thread类API详解

0.线程类常用API大纲

​ Thread() -----> 无参构造方法

​ Thread(RUNABLE) ------> RUNABLE参数的构造方法

​ currentThread() ------> 获取当前线程的方法

​ isAlive() -------> 是否存活方法

​ join() -------> 插队方法

​ (将B线程插入到A线程之前执行,将B线程执行完后,继 续执行A)

​ sleep() ------> 休眠方法

​ yield() -------> 礼让方法

​ getState() -------> 获取当前线程状态

​ interrupt() --------> 停止线程的方法

resume() --------> 唤醒suspended() (已弃用不推荐使用,但还是需要介绍 一下,这是Thread的发展历程)

​ run() --------> 这是继承Thread需要重写的方法

​ start() --------> 线程开启运行方法

stop() --------> ~~stop()~~方法(已弃用不推荐使用,但也同样需要 介绍一下)

suspend() ---------> ~~suspend()~~阻塞线程的方法(已弃用,介绍了解为主)

1.Thread类描述

/**
 * A <i>thread</i> is a thread of execution in a program. The Java
 * Virtual Machine allows an application to have multiple threads of
 * execution running concurrently.
 * 线程指的是一系列执行的程序。JVM允许应用同一时刻多个线程并行执行。
 *
 * <p>
 * Every thread has a priority. Threads with higher priority are
 * executed in preference to threads with lower priority. Each thread
 * may or may not also be marked as a daemon. When code running in
 * some thread creates a new <code>Thread</code> object, the new
 * thread has its priority initially set equal to the priority of the
 * creating thread, and is a daemon thread if and only if the
 * creating thread is a daemon.
 * 词汇:priority 优先   daemon 守护进程    initially 最初
 * 每条线程都拥有一个优先级。高优先级的线程在低优先级的线程之前执行。
 * 每条线程可以被标记为守护进程,也可不被标记为守护进程。
 * 在代码运行在某些线程的时候,创了另一个新的线程对象,新线程 的 最初优先级被赋值成 创建他的线程的优先级,
 * 并且 是一个守护进程线程 当且仅当创建线程的是守护进程。
 *
 * <p>
 * When a Java Virtual Machine starts up, there is usually a single
 * non-daemon thread (which typically calls the method named
 * <code>main</code> of some designated class). The Java Virtual
 * Machine continues to execute threads until either of the following
 * occurs:
 * 词汇:  single 单一的;仅有一个的;单一的;单个的;特指某人或事物;
 *		  non-daemon 非守护进程	
 *		  typically 典型地;通常;一般;典型地;具有代表性地;不出所料;果然;
 *		  designated 命名;指定;选定,指派,委任(某人任某职);标明;标示;指明
 *		  either of 任意一个
 *		  occurs 发生;出现;存在于;出现在
 *		  until 直到...为止
 *		  continues 持续;继续存在;不断发生;继续做;不停地干;(朝相同方向)走,移动;延伸
 * 当JVM启动的时候,通常是一个 单一的非守护进程  线程(通常调用某个指定类的main()方法)。
 * JVM持续执行线程直到下列任意一个情况发生:
 *
 * <ul>
 * <li>The <code>exit</code> method of class <code>Runtime</code> has been
 *     called and the security manager has permitted the exit operation
 *     to take place.
 * <li>All threads that are not daemon threads have died, either by
 *     returning from the call to the <code>run</code> method or by
 *     throwing an exception that propagates beyond the <code>run</code>
 *     method.
 * </ul>
 * 词汇: security 安全    
 *		 take place 发生;举行
 *		 either ... or ... 要么...或者...  不是...就是...
 *		 propagates 传播
 * 	1. 在类 执行 Runtime 代码的时期 调用 exit() 的时候 并且 安全管理已经允许退出操作 发生。
 *	2. 所有不是守护进程 的线程已经 死亡,不是 通过 调用 run() 返回的 就是通过 在run() 抛出异常
 * <p>
 * There are two ways to create a new thread of execution. One is to
 * declare a class to be a subclass of <code>Thread</code>. This
 * subclass should override the <code>run</code> method of class
 * <code>Thread</code>. An instance of the subclass can then be
 * allocated and started. For example, a thread that computes primes
 * larger than a stated value could be written as follows:
 * 词汇: declare 声明
 *		 allocated 分配;拨…(给);划…(归);分配…(给);
 *		 computes primes 计算素数
 * 介绍两种方式去创建一个新线程去执行。一种是声明一个类作为Thread 的子类。
 * 这个子类应该重写Thread类的 run()。子类的实例稍后会被分配和开始。
 * 例如,一个比开始数字大的素数计算可能被写成如下的方式:
 *
 * <hr><blockquote><pre>
 *     class PrimeThread extends Thread {
 *         long minPrime;
 *         PrimeThread(long minPrime) {
 *             this.minPrime = minPrime;
 *         }
 *
 *         public void run() {
 *             // compute primes larger than minPrime
 *             &nbsp;.&nbsp;.&nbsp;.
 *         }
 *     }
 * </pre></blockquote><hr>
 * <p>
 * The following code would then create a thread and start it running:
 * 下列代码将会被创建成1个线程并开始运行:
 * <blockquote><pre>
 *     PrimeThread p = new PrimeThread(143);
 *     p.start();
 * </pre></blockquote>
 * <p>
 * The other way to create a thread is to declare a class that
 * implements the <code>Runnable</code> interface. That class then
 * implements the <code>run</code> method. An instance of the class can
 * then be allocated, passed as an argument when creating
 * <code>Thread</code>, and started. The same example in this other
 * style looks like the following:
 * 另一创建一个线程的方式是声明一个类去现实Runable接口。这个类的实例将会被分配,作为一个参数传递当创建线程
 * 的时候,并且开启。同样列出另一种形式 看起来想下列一样:
 *
 * <hr><blockquote><pre>
 *     class PrimeRun implements Runnable {
 *         long minPrime;
 *         PrimeRun(long minPrime) {
 *             this.minPrime = minPrime;
 *         }
 *
 *         public void run() {
 *             // compute primes larger than minPrime
 *             &nbsp;.&nbsp;.&nbsp;.
 *         }
 *     }
 * </pre></blockquote><hr>
 * <p>
 * The following code would then create a thread and start it running:
 * 下列代码将会被创建成1个线程并开始运行:
 * <blockquote><pre>
 *     PrimeRun p = new PrimeRun(143);
 *     new Thread(p).start();
 * </pre></blockquote>
 * <p>
 * Every thread has a name for identification purposes. More than
 * one thread may have the same name. If a name is not specified when
 * a thread is created, a new name is generated for it.
 * 每一个线程有一个独一无二的  目的  名字。超过一个线程具有相同的名字。
 * 如果在创建的时候没有被明确规定,将会给他自动生成一个新的名字
 * <p>
 * Unless otherwise noted, passing a {@code null} argument to a constructor
 * or method in this class will cause a {@link NullPointerException} to be
 * thrown.
 * 词汇: Unless otherwise 除非另有规定  noted 注意;留意;指出;特别提到(v.) (以…)见称,闻名,著名(adj)
 * 除非另有规定指出, 在当前类中,传递null 参数给构造器 或者 方法 会造成 NullPointerException 
 * 的异常被抛出。
 *
 * @author  unascribed
 * @see     Runnable
 * @see     Runtime#exit(int)
 * @see     #run()
 * @see     #stop()
 * @since   JDK1.0
 */

​ Thread类的描述中,获取到如下信息:

  1. 线程概念:线程指的是一系列执行的程序。JVM允许应用同一时刻多个线程并行执行。
  2. Thread引入时间,JDK1.0时,就已经引入了
  3. 线程会保持运行,但是下了情况,会造成退出线程:
    1. 在代码运行时期,调用了exit()
    2. 所有不是守护进程的线程已经死亡,不是run()正常执行返回执行结果就是run()抛出异常
  4. 可以通过逻辑分析出,守护进程的概念:去开启其他线程的 线程称作 守护进程
  5. 线程使用的两种方式:
    1. 一种是继承Thread并重写run(),run()中写的就是业务逻辑
    2. 另一种是实现Runable接口,也是在run()中写相应的业务逻辑

2.线程API详解:

2.1.Thread() 无参构造方法

/**
 * Allocates a new {@code Thread} object. This constructor has the same
 * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
 * {@code (null, null, gname)}, where {@code gname} is a newly generated
 * name. Automatically generated names are of the form
 * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
 * 词汇: Allocates 拨…(给);划…(归);分配…(给)
 *		 effect 影响;效应;结果	
 *		 automatically (adv.)自动地;机械地;无意识地
 *		 constructor 建造者,制造者,建造商
 *		 generated 生成
 * 分配给新的Thread对象资源。这个构造方法会对 Thread(ThreadGroup,Runable,String) 
 * init(null,null,gname) 这个构造方法有同样影响,gname 是一个自动生成的新的名词。
 * 自动生成名字是 Thread + n 的格式,n代表的是一个数字
 * 
 */
public Thread() {
    init(null, null, "Thread-" + nextThreadNum(), 0);
}

Thread()无参构造方法中调用的init()

/**
 * Initializes a Thread with the current AccessControlContext.
 * @see #init(ThreadGroup,Runnable,String,long,AccessControlContext,boolean)
 * 初始一个当前访问控制上下文的线程
 */
private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize) {
    init(g, target, name, stackSize, null, true);
}

​ 初始化操作代码并没有直接写在第一层的Init方法,而是调用了一个方法,这里多写一层,这种方式封装,可以减少重复代码的出现。

/**
 * Initializes a Thread.
 * 初始化线程
 *
 * @param g the Thread group
 * 参数 g  线程组
 * @param target the object whose run() method gets called
 * 参数 target 被调用的run()
 * @param name the name of the new Thread
 * 参数 name 新线程的名称
 * @param stackSize the desired stack size for the new thread, or
 *        zero to indicate that this parameter is to be ignored.
 * 词汇: desired 渴望的
 *		 indicate 表名;显示
 * 参数 stackSize 新线程期望的栈大小,若被表明是0,那这个参数被忽视
 * @param acc the AccessControlContext to inherit, or
 *            AccessController.getContext() if null
 * 词汇:  inherit 继承
 * 参数 acc 继承自 访问控制上线文 , 或者 访问控制 获取的内容 是空
 * @param inheritThreadLocals if {@code true}, inherit initial values for
 *            inheritable thread-locals from the constructing thread
 * inheritThreadLocals 如果是 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 */
        // applet 小应用程序
        // 通过ThreadGroup 确定是不是小应用程序
        
        /* 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. */
    // explicitly 明确地
    // 检查访问 不管线程组 明确的传递
    g.checkAccess();

    /*
     * Do we have the required permissions?
     * 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();
}

​ 对于init()方法并没有全部翻译,但是需要总结一下思路

​ init()方法中 描述了 线程初始化会关联到线程组的问题,系统安全行问题,而这里被抽象成了两个,一个是ThreadGroup,另一个是 SecurityManager 类,这里体现出java比较核心的思维,就是单一职责性,我确实要与其他类结偶,但是只是在init的时候,与前两者产生了关联。

2.2 Thread(RUNABLE)

/**
 * Allocates a new {@code Thread} object. This constructor has the same
 * effect as {@linkplain #Thread(ThreadGroup,Runnable,String) Thread}
 * {@code (null, target, gname)}, where {@code gname} is a newly generated
 * name. Automatically generated names are of the form
 * {@code "Thread-"+}<i>n</i>, where <i>n</i> is an integer.
 *
 * @param  target
 *         the object whose {@code run} method is invoked when this thread
 *         is started. If {@code null}, this classes {@code run} method does
 *         nothing.
 * 参数 target  在线程开始时被调用的run(),如果 target 是空, 当前的 run() 什么都不做
 */
public Thread(Runnable target) {
    init(null, target, "Thread-" + nextThreadNum(), 0);
}

2.3 currentThread()

/**
 * Returns a reference to the currently executing thread object.
 * 返回当前正在执行的线程
 * @return  the currently executing thread.
 */
public static native Thread currentThread();

​ 获取当前线程的方式一个本地方法,想要查看该方法的内容,需要看其他语言写的实现

2.4 isAlive()

/**
 * Tests if this thread is alive. A thread is alive if it has
 * been started and has not yet died.
 * 测试当前线程是否存货. 线程存活指的是已经被开始,并且还没死亡
 *
 * @return  <code>true</code> if this thread is alive;
 *          <code>false</code> otherwise.
 * 返回值 线程还存活返回true 
 * 		 其他情况就返回false
 */
public final native boolean isAlive();

2.5 join()

​ 在本人写的 https://blog.csdn.net/zhu19920908/article/details/90487018 该文中有介绍过该方法,就不重复介绍了

2.6 sleep()

/**
 * Causes the currently executing thread to sleep (temporarily cease
 * execution) for the specified number of milliseconds, subject to
 * the precision and accuracy of system timers and schedulers. The thread
 * does not lose ownership of any monitors.
 * 词汇 temporarily 暂时地
 	   cease 停止
 	   precision 精确;准确;细致
 	   subject 受...支配
 	   schedulers 程序调度
	   ownership 所有权
 * 造成当前线程执行休眠(暂时地停止执行)一段特定的毫秒时,准度和精度收系统计时器和调度程序所支配。
 * 线程并没有失去监视器的所有权
 *
 * @param  millis
 *         the length of time to sleep in milliseconds
 * millis 休眠的毫秒时间
 * @throws  IllegalArgumentException 
 *          if the value of {@code millis} is negative
 * IllegalArgumentException 当参数是负数的时候抛出该异常
 * @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 static native void sleep(long millis) throws InterruptedException;

​ 虽然是本地方法,但是sleep() 的注释中提到了比较重要的一点信息是sleep()并不会失去监视器的所有权,意味着sleep()并不会释放锁。

2.7 yield()

/**
 * A hint to the scheduler that the current thread is willing to yield
 * its current use of a processor. The scheduler is free to ignore this
 * hint.
 * 词汇:hint 暗示
 * 给程序调度一个暗示 当前线程愿意 让出 使用的处理器。程序调度 空闲时忽略暗示
 *
 *
 * <p> Yield is a heuristic attempt to improve relative progression
 * between threads that would otherwise over-utilise a CPU. Its use
 * should be combined with detailed profiling and benchmarking to
 * ensure that it actually has the desired effect.
 * 词汇:heuristic 启发式的
 *		attempt 尝试
 *		improve 改善
 *		relative 相对的
 *		over-utilise 过度使用
 		combined 组合的
		profiling (有关人或事物的)资料搜集
		benchmarking 标杆管理(n)
 * 让步是一种启发式的尝试改善线程间的相对进展,否者将会造成一个CPU过度使用的情况
 * 分析上诉这种情况应该结合 详细的资料 和 标杆 来确定他是否达到了预期的影响
 *
 *		
 * <p> It is rarely appropriate to use this method. It may be useful
 * for debugging or testing purposes, where it may help to reproduce
 * bugs due to race conditions. It may also be useful when designing
 * concurrency control constructs such as the ones in the
 * {@link java.util.concurrent.locks} package.
   词汇:reproduce 复制,再现
   		race  比赛;参加比赛;使比赛;让…参加速度比赛;(使)快速移动,快速运转
   		constructs (根据不总是真实的各种证据得出的)构想,观念,概念;
 * 这是一个罕有的占用使用当前方法。它可能 用来调试和测试 目的,它对快速运转条件下的
 * 的bug有帮助。 它也是有用的当设计并发 控制 概念 例如 java.util.concurrent.locks 包
 * 
 */
public static native void yield();

​ yield()是一个本地方法,具体实现无法获知,但是根据描述,yield() 方法做了一件事情,当线程执行的时间很久的时候,会长时间的占有 多核CPU中的某一个,而造成其他CPU得不到使用,并且说这个方法使用的很少,但是这个方法对再现bug 和 并发控制 概念很有帮助。

​ 这里简单了,看了下java.util.concurrent.locks包里面有jdk1.5 ,1.6 ,1.8时期维护进去的内容,鬼知道Doug Lee想到了什么,我觉得这个让步方法让我想到更多的是负载均衡方面的内容多写。

2.8 getState()

/**
 * Returns the state of this thread.
 * This method is designed for use in monitoring of the system state,
 * not for synchronization control.
 * 返回向前线程的状态。
 * 这个方法被设计成监视当前系统状态使用,而不是同步控制。
 *
 * @return this thread's state.
 * @since 1.5
 */
public State getState() {
    // get current thread state
    return sun.misc.VM.toThreadState(threadStatus);
}

2.9 interrupt()

/**
 * Interrupts this thread.
 * 终止当前线程
 *
 * <p> Unless the current thread is interrupting itself, which is
 * always permitted, the {@link #checkAccess() checkAccess} method
 * of this thread is invoked, which may cause a {@link
 * SecurityException} to be thrown.
 * 除非当前线程正在终止自身,这是被允许的,checkAccess()是当前线程是否被调用,
 * 可能造成SecurityException被抛出
 *
 * <p> If this thread is blocked in an invocation of the {@link
 * Object#wait() wait()}, {@link Object#wait(long) wait(long)}, or {@link
 * Object#wait(long, int) wait(long, int)} methods of the {@link Object}
 * class, or of the {@link #join()}, {@link #join(long)}, {@link
 * #join(long, int)}, {@link #sleep(long)}, or {@link #sleep(long, int)},
 * methods of this class, then its interrupt status will be cleared and it
 * will receive an {@link  InterruptedException}.
 * 如果当前线程处于阻塞状态 是通过 Object类的 wait() , wait(long),或者 wait(long,int)
 * 或者 是 通过 本类的 join(), join(long) , join(long,int) sleep(long) , sleep(long,int)
 * 线程的打断状态(Thread类里面的一个属性) 将被清理 并且收到 InterruptedException
 *
 * <p> If this thread is blocked in an I/O operation upon an {@link
 * java.nio.channels.InterruptibleChannel InterruptibleChannel}
 * then the channel will be closed, the thread's interrupt
 * status will be set, and the thread will receive a {@link
 * java.nio.channels.ClosedByInterruptException}.
 * 如果这些线程的阻塞在 I/O 操作上面 InterruptibleChannel 异常,然后 通道被关闭,
 * 线程的打断状态(Thread类里面的一个属性) 将被赋值,并且将会收到ClosedByInterruptException异常
 *
 * <p> If this thread is blocked in a {@link java.nio.channels.Selecto}
 * then the thread's interrupt status will be set and it will return
 * immediately from the selection operation, possibly with a non-zero
 * value, just as if the selector's {@link
 * java.nio.channels.Selector#wakeup wakeup} method were invoked.
 * 如果线程处于阻塞 在 Selecto的时候 线程的打断状态(Thread类里面的一个属性)
 * 将被赋值 成 立刻获得的选择操作的值,可能是 是一个非 0 值, 正在 当selector's.wakeup()被调用的时候
 *
 * <p> If none of the previous conditions hold then this thread's interrupt
 * status will be set. </p>
 * 如果 没有一个 以前的 条件 持有 那么 这个 线程的 终止状态 将被赋值
 *
 * <p> Interrupting a thread that is not alive need not have any effect.
 * 中断一个非活动线程不需要有任何效果
 *
 * @throws  SecurityException
 *          if the current thread cannot modify this thread
 * 如果当前线程不能修改本线程会抛出 SecurityException
 *
 * @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();
}

​ 在6.0的时候修订过, 规格是 jsr - 51

2.10 resumes()

/**
 * Resumes a suspended thread.
 * 词汇: resumes  重新开始;(中断后)继续;恢复席位 / 地位 / 职位
 * 		 suspended  悬;挂;吊;暂停;中止;使暂停发挥作用(或使用等);延缓;暂缓;推迟
 * 继续已经挂起的线程
 * <p>
 * First, the <code>checkAccess</code> method of this thread is called
 * with no arguments. This may result in throwing a
 * <code>SecurityException</code> (in the current thread).
 * <p>
 * 首先, 该线程调用的是无参的checkAccess()。
 * 这也许会造成抛出SecurityException的结果
 * If the thread is alive but suspended, it is resumed and is
 * permitted to make progress in its execution.
 * 如果线程是存活且处于挂起状态,那么它将继续并且被允许在执行过程中取得的进展
 * 描述的就是说,如果当前线程是处于suspended造成的挂起装状态,那么将继续执行suspended后的代码
 *
 * @exception  SecurityException  if the current thread cannot modify this
 *               thread.
 * @see        #checkAccess
 * @see        #suspend()
 * @deprecated This method exists solely for use with {@link #suspend},
 *     which has been deprecated because it is deadlock-prone.
 *     For more information, see
 *     <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *     are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 * 词汇: solely	仅,只,唯;单独地
 * 		 deadlock-prone 死锁
 * 这个方法金鱼suspend方法成对使用,由于容易造成死锁,所以弃用
 */
@Deprecated
public final void resume() {
    checkAccess();
    resume0();
}

​ @Deprecated 该注解代表的 是 废弃;不赞成;弃用;不推荐使用;不建议使用 注解

​ resume/suspended 成对使用,并简单的描述了一下弃用的原因,说是太容易造成死锁

2.11 run()

/**
 * If this thread was constructed using a separate
 * <code>Runnable</code> run object, then that
 * <code>Runnable</code> object's <code>run</code> method is called;
 * otherwise, this method does nothing and returns.
 * <p>
 * 词汇:separate 分离
 * 如果线程构建使用分离的Runnable 对象,那么Runnable对象的run()将被调用
 * 否则,该方法什么也不做并且无返回
 * Subclasses of <code>Thread</code> should override this method.
 * Thread的子类应该重写该方法
 *
 * @see     #start()
 * @see     #stop()
 * @see     #Thread(ThreadGroup, Runnable, String)
 */
@Override
public void run() {
    if (target != null) {
        target.run();
    }
}

2.12 start()

/**
 * Causes this thread to begin execution; the Java Virtual Machine
 * calls the <code>run</code> method of this thread.
 * 使当前现线程开始执行;JVM调用当前线程的run()
 * <p>
 * The result is that two threads are running concurrently: the
 * current thread (which returns from the call to the
 * <code>start</code> method) and the other thread (which executes its
 * <code>run</code> method).
 * <p>
 * 结果是两个线程并行运行:当前线程(指从调用返回到start())并且 其他线程(指执行run()线程)
 *
 * It is never legal to start a thread more than once.
 * In particular, a thread may not be restarted once it has completed
 * execution.
 * 词汇: legal  合法的
 * 一次开启多个线程从不是合法的。
 * 在某些特定的情况下,一个相册将不会再次重新启动它已经完成执行
 *
 * @exception  IllegalThreadStateException  if the thread was already
 *               started.
 * @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.
     * 不为主方法线程或“系统”调用此方法
       将由虚拟机创建/设置 线程的分组。添加的任何新功能
       能还必须将此方法添加到VM中。
     * 
     * A zero status value corresponds to state "NEW".
     * 词汇:corresponds  对应的
     * 0 对应的是 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 */
        }
    }
}

2.13 stop()

/**
 * Forces the thread to stop executing.
 * 迫使线程终止执行
 *
 * <p>
 * If there is a security manager installed, its <code>checkAccess</code>
 * method is called with <code>this</code>
 * as its argument. This may result in a
 * <code>SecurityException</code> being raised (in the current thread).
 * <p>
 * 如果安装了安全管理器,他的 checkAccess() 是通过 this 参数调用的。这个可能导致
 * 安全异常被提升(在当前线程中)。
 *
 * If this thread is different from the current thread (that is, the current
 * thread is trying to stop a thread other than itself), the
 * security manager's <code>checkPermission</code> method (with a
 * <code>RuntimePermission("stopThread")</code> argument) is called in
 * addition.
 * 如果此线程与 当前线程 不同(意味着,当前线程正在尝试停止自身以外的 另一个线程),
 * 安全管理的 checkPermission() (即 参数为 "stopThread" 的 RuntimePermission) 被
 * 调用
 *
 * Again, this may result in throwing a
 * <code>SecurityException</code> (in the current thread).
 * 再一次强调,这将导致当前线程抛出一个安全异常
 * <p>
 * The thread represented by this thread is forced to stop whatever
 * it is doing abnormally and to throw a newly created
 * <code>ThreadDeath</code> object as an exception.
 * <p>
 * 词汇: represented by  以...为代表
 		 abnormally	异常地
 * 以被强制停止的线程为代表的,无论什么时候,这种做法是一次的,并且抛出一个新创建的 ThreadDeath 对象作为异  	* 常
 *
 * It is permitted to stop a thread that has not yet been started.
 * If the thread is eventually started, it immediately terminates.
 * 词汇: eventually  最后
 * 他被允许来停止一个还没开始的线程。如果线程最后开始,那么他立即终止。
 * 
 * <p>
 * An application should not normally try to catch
 * <code>ThreadDeath</code> unless it must do some extraordinary
 * cleanup operation (note that the throwing of
 * <code>ThreadDeath</code> causes <code>finally</code> clauses of
 * <code>try</code> statements to be executed before the thread
 * officially dies).  If a <code>catch</code> clause catches a
 * <code>ThreadDeath</code> object, it is important to rethrow the
 * object so that the thread actually dies.
 * <p>
 * 词汇: extraordinary 特别的
 * 一个应用通常不应该尝试捕捉 ThreadDeath 除非 他做了一些特别的清理操作
 * (注意 抛出 ThreadDeath 的原因 是 finally 代码块)
 *
 * The top-level error handler that reacts to otherwise uncaught
 * exceptions does not print out a message or otherwise notify the
 * application if the uncaught exception is an instance of
 * <code>ThreadDeath</code>.
 *
 *顶级错误处理程序,对其他未捕获的错误进行响应
 *异常不会打印出消息或以其他方式通知
 *如果未捕获的异常是
 *<code>threaddeath<code>。
 *
 * @exception  SecurityException  if the current thread cannot
 *               modify this thread.
 * @see        #interrupt()
 * @see        #checkAccess()
 * @see        #run()
 * @see        #start()
 * @see        ThreadDeath
 * @see        ThreadGroup#uncaughtException(Thread,Throwable)
 * @see        SecurityManager#checkAccess(Thread)
 * @see        SecurityManager#checkPermission
 * @deprecated This method is inherently unsafe.  Stopping a thread with
 *       Thread.stop causes it to unlock all of the monitors that it
 *       has locked (as a natural consequence of the unchecked
 *       <code>ThreadDeath</code> exception propagating up the stack).  If
 *       any of the objects previously protected by these monitors were in
 *       an inconsistent state, the damaged objects become visible to
 *       other threads, potentially resulting in arbitrary behavior.  Many
 *       uses of <code>stop</code> should be replaced by code that simply
 *       modifies some variable to indicate that the target thread should
 *       stop running.  The target thread should check this variable
 *       regularly, and return from its run method in an orderly fashion
 *       if the variable indicates that it is to stop running.  If the
 *       target thread waits for long periods (on a condition variable,
 *       for example), the <code>interrupt</code> method should be used to
 *       interrupt the wait.
 *       For more information, see
 *       <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *       are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 * 		该方法天生的不安全。 如果是使用Thread.stop() 将造成 解锁所有的监视器
 */
@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());
}

​ 这个stop()终止线程,并且清除监视器锁的信息,但是可能导致线程安全的问题,jdk不建议使用

​ 例如:

public class Demo{
    
}

2.14 suspends()

/**
 * Suspends this thread.
 * 挂起当前线程
 * <p>
 * First, the <code>checkAccess</code> method of this thread is called
 * with no arguments. This may result in throwing a
 * <code>SecurityException </code>(in the current thread).
 * <p>
 * 首先,无参的checkAccess()将被调用,这个结果可能导致安全异常
 * If the thread is alive, it is suspended and makes no further
 * progress unless and until it is resumed.
 * 如果线程还存活,那么将被挂起并且没有 进一步的执行 除非 等到 他被唤醒
 *
 * @exception  SecurityException  if the current thread cannot modify
 *               this thread.
 * @see #checkAccess
 * @deprecated   This method has been deprecated, as it is
 *   inherently deadlock-prone.  If the target thread holds a lock on the
 *   monitor protecting a critical system resource when it is suspended, no
 *   thread can access this resource until the target thread is resumed. If
 *   the thread that would resume the target thread attempts to lock this
 *   monitor prior to calling <code>resume</code>, deadlock results.  Such
 *   deadlocks typically manifest themselves as "frozen" processes.
 *   For more information, see
 *   <a href="{@docRoot}/../technotes/guides/concurrency/threadPrimitiveDeprecation.html">Why
 *   are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
 *  该方法被弃用,是由于容易造成死锁,如果目标线程持有监视器锁 保护 一个圆形系统代码,当它挂起的时候,
 *  没有线程能连接这部分资源,知道目标线程被唤醒。如果尝试获取监视器锁的 线程先执行了resume(),就会
 *  死锁。这样的死锁通常表现为“冻结”的进程
 */
@Deprecated
public final void suspend() {
    checkAccess();
    suspend0();
}

1.源码阅读技巧总结,当源码中出现<code></code>标签的时候,指的是代码部分的内容

​ eg. <code>exit</code> method 代表的是代码部分的退出方法

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值