一. 线程间的通信
定义
多个线程并发执行时,默认情况下CPU是随机切换线程的
如果我们希望他们有规律的执行, 就可以使用通信
线程之间也不是直接干预某个线程,也是随机的
常用方法
wait() 让当前线程处于等待状态,并释放锁
notify() 唤醒某个等待中的线程
notifyAll() 唤醒所有等待中的线程
注意事项
线程间的所有通信行为都必须在同步代码块中执行
这些行为都是锁调用的
当一个线程陷入等待, 线程会释放掉锁, 并且无法动弹, 即使被唤醒了, 也仅仅表示有了获取锁的机会, 只有当真正获取到锁的时候才能继续运行
wait方法还有重载的方法,可以传入毫秒值,表示多少毫秒之后当前线程自动唤醒
一个锁只能唤醒被自己锁定的线程
无法在当前同步代码块内操作别的锁
二. ThreadLocal
定义
ThreadLocal是线程的本地变量, 是一个存储变量的容器, 存入到这个容器中的变量可以在线程的任何位置取出.
ThreadLocal中的变量是使用线程分离的, 别的线程无法使用,保证了变量的安全性
三. 互斥锁
定义
使用ReentrantLock类代替synchronized关键字, 提供了锁定和解锁的方法
提供了更多的操作所得方法
常用方法
lock() 锁定当前线程
unlock() 解锁
newCondition() 获取可以操作线程等待和唤醒的Condition对象
await() 让当前线程陷入等待
signal() 唤醒某个被锁定的线程
注意事项
互斥锁提供了更多的操作线程的方法供我们使用
Condition对象允许我们在任意锁内唤醒任意线程
前提是使用统一把锁(同一个ReentrantLock对象)
四. 线程的七种状态
状态解析
初始状态 : 线程对象创建完成
就绪状态 : 线程可以被执行
运行状态 : 线程正在运行中
阻塞状态 : 线程被休眠
等待队列 : 线程陷入无限的等待中
锁池状态 : 线程被唤醒,但没有获取到锁
死亡状态 : 线程执行完毕,被关闭
注意事项
大部分书籍里都讲线程的状态分为5类, 既初始, 就绪, 运行, 阻塞, 死亡
但我们更愿意将阻塞状态细分出来, 因为 阻塞, 等待队列, 锁池, 完全是不同的性质
五. 线程组(了解)
定义
Java中使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序直接对线程组进行控制。
提供了一些操作整体的方法, 比如设置组中线程的权限,销毁所有所有线程等等
六. 线程池(了解)
定义
程序启动一个新线程成本是比较高的,因为它涉及到要与操作系统进行交互。而使用线程池可以很好的提高性能,尤其是当程序中要创建大量生存期很短的线程时,更应该考虑使用线程池。线程池里的每一个线程代码结束后,并不会死亡,而是再次回到线程池中成为空闲状态,等待下一个对象来使用
在JDK5之前,我们必须手动实现自己的线程池,从JDK5开始,Java内置支持线程池
七. Runtime类
定义
这是一个单例类, 可以运行系统命令
八. Timer类
定义
定时器, 可以在指定时间执行任务, 可以重复执行
其实就是在指定时间去调用某个方法
任务类必须继承TimerTask类,并且重写run()方法
常用方法
schedule(TimerTask task,Date time ) 安排在执行时间执行任务
schedule(TimerTask task,Date time , long period) 安排在指定时间开始执行任务, 并按固定时间长度重复执行
schedule(TimerTask task, long delay) 从当前时间延迟一段时间执行任务
schedule(TimeTask task,long delay,long period) 从当前时间延迟一段时间执行任务,并按固定时间长度重复执行
总结:
线程的通信
让多个线程之间可以相互影响 多个线程公用的空间
我们可以控制线程的等待和唤醒 wait() notify() notifyAll
这几个方法都必须用在锁的范围内 只对同步代码块有效
当有多个线程处于等待状态时, notify只能随机唤醒一个
锁,只能唤醒被自己等待的线程
ThreadLocal
线程本地变量
可以存储一个值, 线程隔离的, 当前线程存放的值, 其他线程无法获取
底层原来: 一个以线程唯一标识为key的map集合
互斥锁
synchronized的升级版本, 提供了更加丰富的方法
目前给我们的只管体现: 一个锁可以有多个Condition用来等待唤醒不同的线程
比synchronized功能丰富, 但,先对的,编码复杂度也有所提升
线程的状态
新建 : 线程的出生, 创建Thread对象
就绪 : 线程可以执行,但没有获取到cpu的执行权
运行 : 线程正在运行中
休眠 : 线程处于停止状态, 可以自动醒来, 不会释放锁
等待队列 : 线程陷入永久的等待(也可以只等待一段时间), 释放锁, 需要外力才能唤醒
锁池状态 : 等待中的线程被唤醒就会进入锁池状态, 这时, 具有获取锁的资格, 在获取锁之前, 不能运行
消亡 : 线程运行完毕, 结束程序
线程池
在初始化的时候先创建一批线程存储起来, 等使用的时候直接从容器中获取
优点 : 使用时节约了创建线程的时间 (线程的创建时间远远大与一般的对象)
线程池有多种, 每种线程池都有其特点
线程组
多多个线程进行分组管理, 便于操作
Runtime 和 Timer
Runtime : 帮助我们运行操作系统的底层命令
Timer : 计时器和定时器