Object 类线程相关

wait()

一个线程调用一个共享变量的 wait() 方法时,该线程会被阻塞挂起,直到发生以下事件才返回:

  1. 其他线程调用了该对象的 notify() 或 notifyAll() 方法
  2. 其他线程调用了该线程的 interrupt() 方法,该线程抛 InterruptedException 返回

如果调用 wait() 方法的线程没有获取该对象的监视器锁,则调用 wait() 方法时该线程会抛 IllegalMonitorStateException 异常。

如何获取共享变量的监视器锁?

  1. 执行 synchronized 同步代码块时,使用该共享变量作为参数
  2. 被 synchronized 修饰的方法,调用该共享变量

wait()有可能发生虚假唤醒,也就是没有通知、中断或等待超时就切换到可运行状态了。
所以 wait() 必须在 while(condition) 循环中,防止虚假唤醒

  1. synchronized(obj) {
  2. while (条件不满足) {
  3. obj.wait();
  4. }
  5. }

wait(long timeout)

timeout 毫秒后返回,如果 timeout 为0,则和 wait() 方法一样。

nofity()

唤醒一个在共享变量上调用 wait 系列方法被挂起的线程去竞争锁,具体唤醒哪个随机。
被唤醒的线程不是马上从 wait 方法返回,而是要在获取了共享对象的监视器锁后才可以返回,只有该线程竞争到了锁才能继续执行。

notifyAll()

唤醒所有在该共享变量上调用 wait 方法而被挂起的线程去竞争锁。

Thread 类

join()

等到线程终止

sleep()

让出指定时间的执行权,期间不参与 CPU 调度,但不释放锁。

yield()

让出 CPU 执行权,然后处于就绪状态,不被阻塞挂起,也不释放锁。

void interrupt()

中断线程
设置中断标志为 true,如果该线程没有被 wait、join、sleep,该线程会继续往下执行。

boolean isInterrupted()

判断实例对象是否被中断,不清除中断标志

static boolean interrupted()

检测当前线程是否被中断,是返回 true,并清除中断标志
该方法是静态方法,可以通过 Thread.interrupted() 调用
注意是当前线程,不是实例对象的

守护线程与用户线程

JVM启动时会调用 main 函数,main 函数所在的线程就是一个用户线程。
JVM 同时还启动了其他守护线程,比如垃圾回收线程。

所有用户线程都结束时,JVM 会退出,不管当前是否有守护线程。
设置 线程的 daemon 参数为 true,就是守护线程。

线程状态

  1. /**内部类,线程状态*/
  2. public enum State {
  3. // 还没启动
  4. NEW,
  5. // 可运行状态 正在执行,或等待资源
  6. RUNNABLE,
  7. // 阻塞
  8. BLOCKED,
  9. // 等待, 死等,除非被其他线程唤醒 Object.wait()
  10. WAITING,
  11. // 具有指定等待时间的等待
  12. TIMED_WAITING,
  13. // 终止
  14. TERMINATED;
  15. }

wait、sleep 区别

1.所属的类不同,wait => Object, sleep => Thread
2.调用 wait 会释放锁,sleep 不会释放锁。
3.wait (和 notify)必须在 synchronized 块中调用,sleep 没有约束

Thread 部分源码

  1. class Thread implements Runnable {
  2. /* 类加载时 先 注册本地方法
  3. * 将Thread类中的java方法和一个本地的C/C++函数进行对应
  4. */
  5. private static native void registerNatives();
  6. static {
  7. registerNatives();
  8. }
  9. // 每个线程有自己的名称用来标识自己。但可能多个线程会重名,如果启动时没有创建名字,会自动生成一个。
  10. private volatile String name;
  11. // 线程的优先级(最大值为10,最小值为1,默认值为5)
  12. private int priority;
  13. /* 线程是否是守护进程线程。*/
  14. private boolean daemon = false;
  15. /* 要执行的任务 */
  16. private Runnable target;
  17. /* 此线程的组 */
  18. private ThreadGroup group;
  19. /* 此线程的上下文类加载器 */
  20. private ClassLoader contextClassLoader;
  21. /* 。。。。 */
  22. private AccessControlContext inheritedAccessControlContext;
  23. /* 用于自动为匿名线程编号. */
  24. private static int threadInitNumber;
  25. private static synchronized int nextThreadNum() {
  26. return threadInitNumber++;
  27. }
  28. /* 与此线程相关的ThreadLocal值.
  29. * 此 map 由ThreadLocal类维护. */
  30. ThreadLocal.ThreadLocalMap threadLocals = null;
  31. /*
  32. * 与此线程相关的InheritableThreadLocal值.
  33. * 此映射由InheritableThreadLocal类维护.
  34. */
  35. ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
  36. /*
  37. * 此线程请求的堆栈大小,如果创建者未指定堆栈大小,则为0。这取决于虚拟机对这个数字做任何它喜欢的事情;有些虚拟机会忽略它
  38. */
  39. private long stackSize;
  40. /*
  41. * 在本机线程终止后持续存在的JVM私有状态。
  42. */
  43. private long nativeParkEventPointer;
  44. /*
  45. * Thread ID
  46. */
  47. private long tid;
  48. /* 用于生成线程ID */
  49. private static long threadSeqNumber;
  50. /* 线程状态*/
  51. private volatile int threadStatus = 0;
  52. /* 用于生成线程ID */
  53. private static synchronized long nextThreadID() {
  54. return ++threadSeqNumber;
  55. }
  56. /**
  57. * The argument supplied to the current call to
  58. * java.util.concurrent.locks.LockSupport.park.
  59. * Set by (private) java.util.concurrent.locks.LockSupport.setBlocker
  60. * Accessed using java.util.concurrent.locks.LockSupport.getBlocker
  61. */
  62. volatile Object parkBlocker;
  63. /* The object in which this thread is blocked in an interruptible I/O
  64. * operation, if any. The blocker's interrupt method should be invoked
  65. * after setting this thread's interrupt status.
  66. */
  67. private volatile Interruptible blocker;
  68. private final Object blockerLock = new Object();
  69. /* 设置拦截器字段;从java.nio代码通过sun.misc.SharedSecrets调用*/
  70. void blockedOn(Interruptible b) {
  71. synchronized (blockerLock) {
  72. blocker = b;
  73. }
  74. }
  75. /** 线程可以具有的最小优先级。*/
  76. public final static int MIN_PRIORITY = 1;
  77. /** 分配给线程的默认优先级。*/
  78. public final static int NORM_PRIORITY = 5;
  79. /** 线程可以拥有的最大优先级。*/
  80. public final static int MAX_PRIORITY = 10;
  81. /** 返回当前正在执行的线程 */
  82. public static native Thread currentThread();
  83. /**让出 CPU 时间片*/
  84. public static native void yield();
  85. /** 使当前正在执行的线程休眠(暂时停止)不会释放锁 单位:毫秒 */
  86. public static native void sleep(long millis) throws InterruptedException;
  87. /**
  88. * nanos 时间延长 多少 纳秒,超过 50000 millis++ 执行的还是 sleep(long millis)
  89. */
  90. public static void sleep(long millis, int nanos)
  91. throws InterruptedException {。。。}
  92. private void init(ThreadGroup g, Runnable target, String name,
  93. long stackSize) {
  94. init(g, target, name, stackSize, null, true);
  95. }
  96. /**
  97. * 初始化线程
  98. *
  99. * g 线程组
  100. * target 调用其run()方法的对象
  101. * name 新线程的名称
  102. * stackSize 新线程所需的堆栈大小,零表示要忽略此参数。
  103. * acc 安全控制器 要继承的AccessControlContext,如果为null 则为 AccessController.getContext()
  104. * inheritThreadLocals 继承的 ThreadLocal
  105. */
  106. private void init(ThreadGroup g, Runnable target, String name,
  107. long stackSize, AccessControlContext acc,
  108. boolean inheritThreadLocals) {。。。}
  109. /**Thread类不支持克隆*/
  110. @Override
  111. protected Object clone() throws CloneNotSupportedException {
  112. throw new CloneNotSupportedException();
  113. }
  114. /**无参的构造方法*/
  115. public Thread() {
  116. init(null, null, "Thread-" + nextThreadNum(), 0);
  117. }
  118. /** 启动线程,这个方法是个同步的方法 最终调用 start0 */
  119. public synchronized void start() {}
  120. /**真正启动线程的方法*/
  121. private native void start0();
  122. /**实现 Runnable 接口的 run 方法*/
  123. @Override
  124. public void run() {
  125. if (target != null) {
  126. target.run();
  127. }
  128. }
  129. /**这个方法是JVM调用的,用来做一些清理工作*/
  130. private void exit() {}
  131. /**过时了*/
  132. @Deprecated
  133. public final void stop() {}
  134. /**过时了*/
  135. @Deprecated
  136. public final synchronized void stop(Throwable obj) {
  137. throw new UnsupportedOperationException();
  138. }
  139. /**中断线程*/
  140. public void interrupt() {
  141. if (this != Thread.currentThread())
  142. checkAccess();
  143. synchronized (blockerLock) {
  144. Interruptible b = blocker;
  145. if (b != null) {
  146. interrupt0(); // Just to set the interrupt flag
  147. b.interrupt(this);
  148. return;
  149. }
  150. }
  151. interrupt0();
  152. }
  153. /** 检测当前线程是否被中断,是返回 true,并清除中断标志
  154. 该方法是静态方法,可以通过 Thread.interrupted() 调用
  155. 注意是当前线程,不是实例对象的
  156. */
  157. public static boolean interrupted() {
  158. return currentThread().isInterrupted(true);
  159. }
  160. /**判断 实例对象线程 是否被中断
  161. 传 false,不清除中断标志
  162. */
  163. public boolean isInterrupted() {
  164. return isInterrupted(false);
  165. }
  166. /**判断 实例对象线程 是否被中断 参数:是否清除中断标识*/
  167. private native boolean isInterrupted(boolean ClearInterrupted);
  168. /**过时了*/
  169. @Deprecated
  170. public void destroy() {
  171. throw new NoSuchMethodError();
  172. }
  173. /** native 方法,判断线程是否还活着*/
  174. public final native boolean isAlive();
  175. /**过时了*/
  176. @Deprecated
  177. public final void suspend() {
  178. checkAccess();
  179. suspend0();
  180. }
  181. /**过时了*/
  182. @Deprecated
  183. public final void resume() {
  184. checkAccess();
  185. resume0();
  186. }
  187. /**设置优先级*/
  188. public final void setPriority(int newPriority) {
  189. ThreadGroup g;
  190. checkAccess();
  191. if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
  192. throw new IllegalArgumentException();
  193. }
  194. if((g = getThreadGroup()) != null) {
  195. if (newPriority > g.getMaxPriority()) {
  196. newPriority = g.getMaxPriority();
  197. }
  198. setPriority0(priority = newPriority);
  199. }
  200. }
  201. /**获取优先级*/
  202. public final int getPriority() {
  203. return priority;
  204. }
  205. /**设置线程的名称*/
  206. public final synchronized void setName(String name) {
  207. checkAccess();
  208. if (name == null) {
  209. throw new NullPointerException("name cannot be null");
  210. }
  211. this.name = name;
  212. if (threadStatus != 0) {
  213. setNativeName(name);
  214. }
  215. }
  216. /**获取线程名称*/
  217. public final String getName() {
  218. return name;
  219. }
  220. /**获取线程的线程组*/
  221. public final ThreadGroup getThreadGroup() {
  222. return group;
  223. }
  224. /**获取当前线程所在线程组的活跃线程数,这个值是动态的*/
  225. public static int activeCount() {
  226. return currentThread().getThreadGroup().activeCount();
  227. }
  228. /**将当前进程中的每个活动线程复制到指定的数组中*/
  229. public static int enumerate(Thread tarray[]) {
  230. return currentThread().getThreadGroup().enumerate(tarray);
  231. }
  232. /**过期了*/
  233. @Deprecated
  234. public native int countStackFrames();
  235. /**等该实例对象线程终止,最多等 millis 毫秒, 0表示一直等到终止*/
  236. public final synchronized void join(long millis)
  237. throws InterruptedException {
  238. long base = System.currentTimeMillis();
  239. long now = 0;
  240. if (millis < 0) {
  241. throw new IllegalArgumentException("timeout value is negative");
  242. }
  243. if (millis == 0) {
  244. while (isAlive()) {
  245. wait(0);
  246. }
  247. } else {
  248. while (isAlive()) {
  249. long delay = millis - now;
  250. if (delay <= 0) {
  251. break;
  252. }
  253. wait(delay);
  254. now = System.currentTimeMillis() - base;
  255. }
  256. }
  257. }
  258. /**同上 nanos 超过50万 millis++ */
  259. public final synchronized void join(long millis, int nanos)
  260. throws InterruptedException {。。。}
  261. /**一直等到线程终止*/
  262. public final void join() throws InterruptedException {
  263. join(0);
  264. }
  265. /**打印堆栈,只有debugg的时候使用,平时别用*/
  266. public static void dumpStack() {
  267. new Exception("Stack trace").printStackTrace();
  268. }
  269. /**设置守护线程标志,记得是启动前设置*/
  270. public final void setDaemon(boolean on) {
  271. checkAccess();
  272. if (isAlive()) {
  273. throw new IllegalThreadStateException();
  274. }
  275. daemon = on;
  276. }
  277. /**判断线程是否是守护线程*/
  278. public final boolean isDaemon() {
  279. return daemon;
  280. }
  281. /**检查当前线程是否有权限操作这个实例线程*/
  282. public final void checkAccess() {
  283. SecurityManager security = System.getSecurityManager();
  284. if (security != null) {
  285. security.checkAccess(this);
  286. }
  287. }
  288. /**打印线程的字符串*/
  289. public String toString() {
  290. ThreadGroup group = getThreadGroup();
  291. if (group != null) {
  292. return "Thread[" + getName() + "," + getPriority() + "," +
  293. group.getName() + "]";
  294. } else {
  295. return "Thread[" + getName() + "," + getPriority() + "," +
  296. "" + "]";
  297. }
  298. }
  299. /**获取ClassLoader,注意CallerSensitive这个注解,调用者必须有权限*/
  300. @CallerSensitive
  301. public ClassLoader getContextClassLoader() {
  302. if (contextClassLoader == null)
  303. return null;
  304. SecurityManager sm = System.getSecurityManager();
  305. if (sm != null) {
  306. ClassLoader.checkClassLoaderPermission(contextClassLoader,
  307. Reflection.getCallerClass());
  308. }
  309. return contextClassLoader;
  310. }
  311. /**设置这个ClassLoader*/
  312. public void setContextClassLoader(ClassLoader cl) {
  313. SecurityManager sm = System.getSecurityManager();
  314. if (sm != null) {
  315. sm.checkPermission(new RuntimePermission("setContextClassLoader"));
  316. }
  317. contextClassLoader = cl;
  318. }
  319. /**native方法,判断是否持有锁*/
  320. public static native boolean holdsLock(Object obj);
  321. /**栈帧数组*/
  322. private static final StackTraceElement[] EMPTY_STACK_TRACE
  323. = new StackTraceElement[0];
  324. /**获取线程栈帧*/
  325. public StackTraceElement[] getStackTrace() {...}
  326. /**获取所有线程的ThreadDump*/
  327. public static Map<Thread, StackTraceElement[]> getAllStackTraces() {...}
  328. ...
  329. private native static StackTraceElement[][] dumpThreads(Thread[] threads);
  330. private native static Thread[] getThreads();
  331. /**获取id*/
  332. public long getId() {
  333. return tid;
  334. }
  335. /**内部类,线程状态*/
  336. public enum State {
  337. // 还没启动
  338. NEW,
  339. // 可运行状态 正在执行,或等待资源
  340. RUNNABLE,
  341. // 阻塞
  342. BLOCKED,
  343. // 等待, 死等,除非被其他线程唤醒 Object.wait()
  344. WAITING,
  345. // 具有指定等待时间的等待
  346. TIMED_WAITING,
  347. // 终止
  348. TERMINATED;
  349. }
  350. /**获取线程状态*/
  351. public State getState() {
  352. // get current thread state
  353. return sun.misc.VM.toThreadState(threadStatus);
  354. }
  355. // Added in JSR-166
  356. /**未检查异常处理器
  357. 函数式接口 可以使用Lambda表达式来表示该接口的一个实现 */
  358. @FunctionalInterface
  359. public interface UncaughtExceptionHandler {
  360. /**线程执行任务过程中出现未检查异常时,JVM会调用这个方法*/
  361. void uncaughtException(Thread t, Throwable e);
  362. }
  363. // 未检查异常处理器 除非显式设置,否则为null
  364. private volatile UncaughtExceptionHandler uncaughtExceptionHandler;
  365. // 默认的未检查异常处理器
  366. private static volatile UncaughtExceptionHandler defaultUncaughtExceptionHandler;
  367. /**设置 默认的未检查异常处理器*/
  368. public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
  369. SecurityManager sm = System.getSecurityManager();
  370. if (sm != null) {
  371. sm.checkPermission(
  372. new RuntimePermission("setDefaultUncaughtExceptionHandler")
  373. );
  374. }
  375. defaultUncaughtExceptionHandler = eh;
  376. }
  377. /**获取 默认的未检查异常处理器*/
  378. public static UncaughtExceptionHandler getDefaultUncaughtExceptionHandler(){
  379. return defaultUncaughtExceptionHandler;
  380. }
  381. /**获取 未检查异常处理器*/
  382. public UncaughtExceptionHandler getUncaughtExceptionHandler() {
  383. return uncaughtExceptionHandler != null ?
  384. uncaughtExceptionHandler : group;
  385. }
  386. /**设置 未检查异常处理器*/
  387. public void setUncaughtExceptionHandler(UncaughtExceptionHandler eh) {
  388. checkAccess();
  389. uncaughtExceptionHandler = eh;
  390. }
  391. /** 将异常转发给处理器,这个方法只会被JVM调用 */
  392. private void dispatchUncaughtException(Throwable e) {
  393. getUncaughtExceptionHandler().uncaughtException(this, e);
  394. }
  395. /**清理引用队列 。。。*/
  396. static void processQueue(ReferenceQueue<Class<?>> queue,
  397. ConcurrentMap<? extends
  398. WeakReference<Class<?>>, ?> map)
  399. {
  400. Reference<? extends Class<?>> ref;
  401. while((ref = queue.poll()) != null) {
  402. map.remove(ref);
  403. }
  404. }
  405. /**类对象的弱键**/
  406. static class WeakClassKey extends WeakReference<Class<?>> {}
  407. // The following three initially uninitialized fields are exclusively
  408. // managed by class java.util.concurrent.ThreadLocalRandom. These
  409. // fields are used to build the high-performance PRNGs in the
  410. // concurrent code, and we can not risk accidental false sharing.
  411. // Hence, the fields are isolated with @Contended.
  412. /** 实例线程的随机种子 */
  413. /** @sun.misc.Contended("tlr") 避免多线程下的伪共享,提升效率 */
  414. @sun.misc.Contended("tlr")
  415. long threadLocalRandomSeed;
  416. /** 用来计算随机种子; 随机种子未初始化时为 0 */
  417. @sun.misc.Contended("tlr")
  418. int threadLocalRandomProbe;
  419. /** 用来计算随机种子; 从公共随机序列中分离出二级种子 */
  420. @sun.misc.Contended("tlr")
  421. int threadLocalRandomSecondarySeed;
  422. /* 私有 原生方法 */
  423. private native void setPriority0(int newPriority);
  424. private native void stop0(Object o);
  425. private native void suspend0();
  426. private native void resume0();
  427. private native void interrupt0();
  428. private native void setNativeName(String name);
  429. }