课程咨询: 400-996-5531 / 投诉建议: 400-111-8989
认真做教育 专心促就业
我们在学习java编程开发语言的过程中,对于线程问题讲解的是非常多的。今天,我们就一起来了解一下,在java并发编程中线程中断与线程死锁的一些概念。
一.线程中断
Java 中线程中断是一种线程间协作模式,通过设置线程的中断标志并不能直接终止该线程的执行,而是需要被中断的线程根据中断状态自行处理。
1.void interrupt() 方法:中断线程,例如当线程 A 运行时,线程 B 可以调用线程 A 的 interrupt() 方法来设置线程 A 的中断标志为 true 并立即返回。设置标志仅仅是设置标志,线程 A 并没有实际被中断,会继续往下执行的。如果线程 A 因为调用了 wait 系列函数或者 join 方法或者 sleep 函数而被阻塞挂起,这时候线程 B 调用了线程 A 的 interrupt() 方法,线程 A 会在调用这些方法的地方抛出 InterruptedException 异常而返回。
2.boolean isInterrupted():检测当前线程是否被中断,如果是返回 true,否者返回 false
3.boolean interrupted():检测当前线程是否被中断,如果是返回 true,否者返回 false,与 isInterrupted 不同的是该方法如果发现当前线程被中断后会清除中断标志,并且该函数是 static 方法,可以通过 Thread 类直接调用。另外从下面代码可以知道 interrupted() 内部是获取当前调用线程的中断标志而不是调用 interrupted() 方法的实例对象的中断标志。
二.理解线程上下文切换
在多线程编程中,线程个数一般都大于 CPU 个数,而每个 CPU 同一时刻只能被一个线程使用,为了让用户感觉多个线程是在同时执行,CPU 资源的分配采用了时间片轮转的策略,也就是给每个线程分配一个时间片,在时间片内占用 CPU 执行任务。当前线程的时间片使用完毕后当前就会处于就绪状态并让出 CPU 让其它线程占用,这就是上下文切换,从当前线程的上下文切换到了其它线程。
那么就有一个问题让出 CPU 的线程等下次轮到自己占有 CPU 时候如何知道之前运行到哪里了?
所以在切换线程上下文时候需要保存当前线程的执行现场,当再次执行时候根据保存的执行现场信息恢复执行现场
线程上下文切换时机:
1.当前线程的 CPU 时间片使用完毕处于就绪状态时候;
2.当前线程被其它线程中断时候
总结:由于线程切换是有开销的,所以并不是开的线程越多越好,比如如果机器是4核心的,你开启了100个线程,那么同时执行的只有4个线程,这100个线程会来回切换线程上下文来共享这四个 CPU。
三.线程死锁
什么是线程死锁呢?
死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的互相等待的现象,在无外力作用的情况下,这些线程会一直相互等待而无法继续运行下去。
那么产生死锁的原因都有哪些,学过操作系统的应该都知道死锁的产生必须具备以下四个必要条件。
1.互斥条件:指线程对已经获取到的资源进行排它性使用,即该资源同时只由一个线程占用。如果此时还有其它进行请求获取该资源,则请求者只能等待,直至占有资源的线程用毕释放。
2.请求并持有条件:指一个线程已经持有了至少一个资源,但又提出了新的资源请求,而新资源已被其其它线程占有,所以当前线程会被阻塞,但阻塞的同时并不释放自己已经获取的资源。
3.不可剥夺条件:指线程获取到的资源在自己使用完之前不能被其它线程抢占,只有在自己使用完毕后由自己释放。
4.环路等待条件:指在发生死锁时,必然存在一个线程——资源的环形链,即线程集合{T0,T1,T2,···,Tn}中的 T0 正在等待一个 T1 占用的资源;T1 正在等待 T2 占用的资源,……Tn正在等待已被 T0 占用的资源。
作者:狂小白
节选:博客园
【免责声明】:本内容转载于网络,转载目的在于传递信息。文章内容为作者个人意见,本平台对文中陈述、观点保持中立,不对所包含内容的准确性、可靠性与完整性提供形式地保证。请读者仅作参考。