文章目录
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
* . . .
* }
* }
* </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
* . . .
* }
* }
* </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类的描述中,获取到如下信息:
- 线程概念:线程指的是一系列执行的程序。JVM允许应用同一时刻多个线程并行执行。
- Thread引入时间,JDK1.0时,就已经引入了
- 线程会保持运行,但是下了情况,会造成退出线程:
- 在代码运行时期,调用了exit()
- 所有不是守护进程的线程已经死亡,不是run()正常执行返回执行结果就是run()抛出异常
- 可以通过逻辑分析出,守护进程的概念:去开启其他线程的 线程称作 守护进程
- 线程使用的两种方式:
- 一种是继承Thread并重写run(),run()中写的就是业务逻辑
- 另一种是实现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 代表的是代码部分的退出方法