多线程

线程状态转换图

新建(NEW):新建线程对象,未调用 start 方法
可运行(RUNNABLE):线程对象创建后,被调用 start 方法。此状态的线程位于可运行线程池中,等待获取 CPU 的使用权
运行中(RUNNING):线程获取了 CPU 的使用权,执行程序代码
阻塞(BLOCKED):线程因为某种原因放弃了 CPU 的使用权,暂时停止运行,直到线程进入可运行状态,才有机会再次获取 CPU 的使用权进入运行状态
消亡(DEAD):线程已经执行完毕。主线程 main 方法结束或因异常退出;子线程 run 方法结束或因异常退出

线程常见函数 来源类 是否 Static 说明 是否释放锁
sleep() Thread static 只能操作当前线程。时间到后(没有interrupt的情况下),回到“就绪”状态
yield() Thread static 只能操作当前线程。只让出CPU时间片。不让出持有的锁和其他资源(磁盘IO,内存)
join() Thread no 在线程 B 中调用了线程 A 的 Join()方法,直到线程 A 执行完毕后,才会继续 执行线程 B
         
interrupt() Thread no

可以在A 线程里调用B.interrupt(),只是将B线程的interrupted标志位置为true。

  • 一般情况下,毫无影响。由用户自定义代码处理该标志位改变后的情况。
  • 但当B线程正在sleep,wait,join,B线程自己会立即抛InterruptException异常...详情
interrupted() Thread static 只能操作当前线程。会判断当前线程的interrupted状态,并且会重置该状态为false.
isInterrupted() Thread no 可以在A 线程里调用B.isInterrupted().只是返回被检查线程的标志位情况,不会重置。
         
wait() Object no

针对某一个对象调用:object.wait(). 

  • 会释放当前线程持有的锁,而且当前被唤醒后,会重新 去竞争锁,锁竞争到后才会执行 wait 方法后面的代码
notify()/notifyAll() Object no

针对某一个对象调用:object.notify()

  • 调用 notify()系列方法后,对锁无影响,线程只有在 syn 同步代码执行完后才 会自然而然的释放锁
不 (执行完同步代码块才会释放)

yield()

只让出CPU时间片。持有的锁,还有其他资源(磁盘IO,内存)不让出

  

  • 使当前线程让出 CPU 占有权,但让出的时间是不可设定的。
  • 不会释放锁资源。注意:并不是每个线程都需要这个锁的,而且执行 yield( )的线 程不一定就会持有锁,我们完全可以在释放锁后再调用 yield 方法。
  • 所有执行 yield()的线程有可能在进入到就绪状态后会被操作系统再次选中,马上又被执行。 

join()

此处为常见面试考点
Q: 如何将多线程变为串行? A: 使用join()方法

  

把指定的线程加入到当前线程,可以将两个交替执行的线程合并为顺序执行。

比如在线程 B 中调用了线程 A 的 Join()方法,直到线程 A 执行完毕后,才会继续 执行线程 B。

线程的优先级

在 Java 线程中,通过一个整型成员变量 priority 来控制优先级,优先级的范 围从 1~10,在线程构建的时候可以通过 setPriority(int)方法来修改优先级,默认 优先级是 5,优先级高的线程分配时间片的数量要多于优先级低的线程。

设置线程优先级时,针对频繁阻塞(休眠或者 I/O 操作)的线程需要设置较 高优先级,而偏重计算(需要较多 CPU 时间或者偏运算)的线程则设置较低的 优先级,确保处理器不会被独占。在不同的 JVM 以及操作系统上,线程规划会 存在差异,有些操作系统甚至会忽略对线程优先级的设定。 

原文地址:https://www.cnblogs.com/frankcui/p/12441315.html