线程
# 什么是线程?
线程是进程中一条执行流程,同一个进程内多个线程共享地址空间和文件等资源,每个线程有自己的寄存器和栈;
# 为什么需要线程?
线程创建时间,终止时间比进程快;
进程在创建过程中,需要资源管理信息,如:内存管理信息,文件管理信息;
线程创建过程中,只需要共享这些资源信息;
线程切换比进程切换快;
线程具有相同的地址空间(虚拟内存共享),同一个进程的线程都具有同一个页表,切换的时候不需要切换页表;
线程之间数据交互效率高;
同一进程各线程间共享内存和文件资源,线程之间数据传递时,不需要经过内核;
# 线程上下文切换
- 当两个线程不属于同一个进程:同切换进程;
- 当属于同一个进程:因为虚拟线程是共享的,所以虚拟内存资源保持不动,只需要切换线程的私有数据,寄存器等不共享数据;
# 死锁
互斥条件;
多个线程不能使用同一个资源;
持有并等待条件;
当线程 A 已经持有了资源 1,又想申请资源 2,而资源 2 已经被线程 B持有了,所以线程 A 就会处于等待状态;
线程 A 在等待时不会释放自己的资源;
不可剥夺条件;
线程持有的资源在使用期间不能被其它线程获取;
环路等待条件;
线程 A 已经持有资源 2,而想请求资源 1, 线程 B 已经获取了资源 1,而想请求资源 2,这就形成资源请求等待的环形图;
一般破坏2,4条件:
静态分配策略:破坏持有并等待条件,进程要么占有资源然后开始执行,要么不占有资源,不会占有一些资源等待一些资源的情况;
层次分配策略:破坏环路等待策略,所有资源分成多个层次,一个进程得到某一资源后,只能再申请较高一层的资源;释放某层的一个资源后,必须先释放所占用的较高层的资源;
Java中解决方法:
- 顺序加锁;
- 锁超时释放;
# 线程通信方式
- 互斥锁(Mutex):只有拥有互斥对象的线程才有访问公共资源的权限;
- 读写锁:允许多个线程同时读取共享资源,只有一个线程可以对共享资源进行写操作;
- 信号量(Semaphore):允许同一时刻多个线程访问同一资源,但需要控制同一时刻访问此资源的最大线程数量;
- 信号:Wait/Notify,通知方式保持多线程同步;
- 屏障:同步原语,用于等待多个线程到达某个点再一起继续执行。如CyclicBarrier;