Java并发-线程上下文切换与死锁
创始人
2024-02-16 20:57:21
0

 理解线程的上下文切换

概述:在多线程编程中,线程个数一般都大于 CPU 个数,而每个 CPU 同一时-刻只能被一个线程使用,为了让用户感觉多个线程是在同时执行的, CPU 资源的分配采用了时间片轮转的策略,也就是给每个线程分配一个时间片,线程在时间片内占用 CPU 执行任务

 定义:当前线程使用完时间片后,就会处于就绪状态并让出 CPU,让其他线程占用,这就是上下文切换,从当前线程的切换到了其他线程

线程上下文切换时机: 当前线程的 CPU 时间片使用完或者是当前线程被其他线程中断时,当前线程就会释放执行权。那么此时执行权就会被切换给其他的线程进行任务的执行,一个线程释放,另外一个线程获取,就是我们所说的上下文切换时机。

什么是线程死锁

死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的互相等待的现象,在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去

  •  如上图所示死锁状态,线程 A 己经持有了资源 2,它同时还想申请资源 1,可是此时线程 B 已经持有了资源 1 ,线程 A 只能等待。
  • 反观线程 B 持有了资源 1 ,它同时还想申请资源 2,但是资源 2 已经被线程 A 持有,线程 B 只能等待。所以线程 A 和线程 B 就因为相互等待对方已经持有的资源,而进入了死锁状态。

 线程死锁的必备要素

  • 互斥条件:进程要求对所分配的资源进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待;

两个线程拥有互斥的资源而且都没有释放。

  • 不可剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放,如 yield 释放 CPU 执行权);

没有外力强迫其释放,自己也不能主动释放。

  • 请求与保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放;
  • 循环等待条件:指在发生死锁时,必然存在一个线程请求资源的环形链,即线程集合 {T0,T1,T2,…Tn}中的 T0 正在等待一个 T1 占用的资源,T1 正在等待 T2 占用的资源,以此类推,Tn 正在等待己被 T0 占用的资源。

 

死锁的实现

场景设计

  • 创建 2 个线程,线程名分别为 threadA 和 threadB;
  • 创建两个资源, 使用 new Object () 创建即可,分别命名为 resourceA 和 resourceB;
  • threadA 持有 resourceA 并申请资源 resourceB;
  • threadB 持有 resourceB 并申请资源 resourceA ;
  • 为了确保发生死锁现象,请使用 sleep 方法创造该场景;
  • 执行代码,看是否会发生死锁。

结果如下图所示,线程A获取A资源,线程B获取B资源。然后线程A由想要获取B资源,线程B又想获取A资源,他们谁也没有主动释放。

 代码讲解: 

  • 从代码中来看,我们首先创建了两个资源 resourceA 和 resourceB;
  • 然后创建了两条线程 threadA 和 threadB。threadA 首先获取了 resourceA ,获取的方式是代码 synchronized (resourceA) ,然后沉睡 1000 毫秒;
  • 在 threadA 沉睡过程中, threadB 获取了 resourceB,然后使自己沉睡 1000 毫秒;
  • 当两个线程都苏醒时,此时可以确定 threadA 获取了 resourceA,threadB 获取了 resourceB,这就达到了我们做的第一步,线程分别持有自己的资源;
  • 那么第二步就是开始申请资源,threadA 申请资源 resourceB,threadB 申请资源 resourceA 无奈 resourceA 和 resourceB 都被各自线程持有,两个线程均无法申请成功,最终达成死锁状态。
package jvm.juc;public class DeadLock {private static Object resoureceA = new Object();private static Object resoureceB = new Object();public static void main(String[] args) {Thread threadA = new Thread(()->{System.out.println("线程A-准备获得A资源....");synchronized (resoureceA) {System.out.println("线程A-已经获得A资源");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程A-准备获得B资源");synchronized (resoureceB) {System.out.println("线程A-已经获得B资源");}}});threadA.setName("Thread-A");Thread threadB = new Thread(()->{System.out.println("线程B-准备获得B资源....");synchronized (resoureceB) {System.out.println("线程B-已经获得B资源");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("线程B-准备获得A资源");synchronized (resoureceA) {System.out.println("线程B-已经获得A资源");}}});threadA.setName("Thread-B");threadA.start();threadB.start();}
}

如何避免线程死锁

要想避免死锁,只需要破坏掉至少一个构造死锁的必要条件即可,学过操作系统的读者应该都知道,目前只有请求并持有和环路等待条件是可以被破坏的。

我们,不让他们循环持有相互的资源就行。

package jvm.juc;public class DeadLock {private static Object resoureceA = new Object();private static Object resoureceB = new Object();public static void main(String[] args) {Thread threadA = new Thread(()->{synchronized (resoureceA) {System.out.println("线程A-已经获得A资源");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (resoureceB) {System.out.println("线程A-已经获得B资源");}}});threadA.setName("Thread-A");Thread threadB = new Thread(()->{synchronized (resoureceA) {System.out.println("线程B-已经获得A资源");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (resoureceB) {System.out.println("线程B-已经获得B资源");}}});threadA.setName("Thread-B");threadA.start();threadB.start();}
}

相关内容

热门资讯

新疆火炬(603080)披露公... 截至2025年12月22日收盘,新疆火炬(603080)报收于22.81元,较前一交易日上涨0.35...
原创 “... 福州一轿车在街头逆行,连撞多辆非机动车致5人受伤。警方通报称系“操作不当”,排除酒驾毒驾。但“操作不...
多个岗位招聘限男性当地人社部门... 多个岗位招聘限男性当地人社部门被起诉:怠于履行监管职责
痛惜!年仅40岁!80后法官调... 12月22日,据宁夏日报消息,西吉县人民法院综合审判庭副庭长马春刚,在调解纠纷时突发心脏病倒在办公桌...
天玑科技:因涉嫌串标,公司及相... 12月22日,天玑科技(300245.SZ)发布公告称,公司近日收到上海市虹口区人民检察院送达的《起...
交建股份实际控制人因涉嫌犯罪被... 12月22日晚,交建股份公告,公司实际控制人俞发祥因涉嫌犯罪被绍兴市公安局采取刑事强制措施,案件正在...
涉嫌串通投标,这家上市公司被起... 12月22日,天玑科技(300245.SZ)公告称,公司于近日收到上海市虹口区人民检察院送达的《起诉...
40项试点经验及实践案例入围广... 中新网南宁12月22日电(林浩)广西壮族自治区商务厅22日介绍,中国(广西)自由贸易试验区第七批自治...
突发!祥源文旅董事长俞发祥涉嫌... 【大河财立方消息】12月22日,浙江祥源文旅股份有限公司(证券简称:祥源文旅)公告,收到公司实际控制...
祥源文旅:实控人俞发祥因涉嫌犯... 祥源文旅12月22日晚间公告,公司实际控制人俞发祥因涉嫌犯罪被绍兴市公安局采取刑事强制措施,案件正在...