茂展的分享博客

多线程总结(二)

多线程总结(一)

java多线程中的死锁、活锁、饥饿、无锁

死锁

死锁是多线程中最差的一种情况,多个线程相互占用对方的资源的锁,而又相互等对方释放锁,此时若无外力干预,这些线程则一直处理阻塞的假死状态,形成死锁

活锁

活锁这个概念大家应该很少有人听说或理解它的概念,而在多线程中这确实存在。活锁恰恰与死锁相反,死锁是大家都拿不到资源都占用着对方的资源,而活锁是拿到资源却又相互释放不执行。当多线程中出现了相互谦让,都主动将资源释放给别的线程使用,这样这个资源在多个线程之间跳动而又得不到执行,这就是活锁。

饥饿

我们知道多线程执行中有线程优先级这个东西,优先级高的线程能够插队并优先执行,这样如果优先级高的线程一直抢占优先级低线程的资源,导致低优先级线程无法得到执行,这就是饥饿。当然还有一种饥饿的情况,一个线程一直占着一个资源不放而导致其他线程得不到执行,与死锁不同的是饥饿在以后一段时间内还是能够得到执行的,如那个占用资源的线程结束了并释放了资源。

无锁

无锁,即没有对资源进行锁定,即所有的线程都能访问并修改同一个资源,但同时只有一个线程能修改成功。无锁典型的特点就是一个修改操作在一个循环内进行,线程会不断的尝试修改共享资源,如果没有冲突就修改成功并退出否则就会继续下一次循环尝试。所以,如果有多个线程修改同一个值必定会有一个线程能修改成功,而其他修改失败的线程会不断重试直到修改成功。之前的文章我介绍过JDK的CAS原理及应用即是无锁的实现

并发编程中的三个概念

原子性

原子性:即一个操作或多个操作要不 不执行且执行过程不会被任何外界因素所打断,要么不执行

可见性

可见性指的是当多个线程访问同一个变量时,一个线程修改了这个变量的值,其他线程能够立即看到修改的值

有序性

有序性指的是程序的执行的顺序按照代码的先后顺序执行。

什么是守护线程(Daemon)

通俗的例子就是任何一个守护线程都是JVM中非守护线程的“保姆”
只要当前JVM实例存在一个没有结束的非守护线程,那么守护线程就会全部运行。只有当最后一个非守护线程结束的时候,守护线程会随着JVM一起结束工作。

用户线程和线程区别

几乎一样,唯一区别是,JVM的离开,如果用户进程全部退出了,那么守护进程和JVM一起结束,因为没有了守护者,守护进程就没有守护的进程的意义,所以没有继续运行的必要性了

典型的守护进程

GC线程,只要有用户线程在,垃圾收集线程就不会退出。

注意点

  1. 设置setDaemon(true)必须在new Thread().start执行之前执行,普通线程不可以转换成守护线程
  2. 守护线程内部产生的新线程也是守护线程
  3. 并不是所有的应用都可以分配Daemon来守护,例如读写操作或计算逻辑

void setDaemon(boolean on) 标志着该线程是 守护线程或用户线程 on可以取true或者false

多线程下的异常如何处理

异常不同处理的方式不同

  1. 非运行时异常(UnCheckedException)
    多线程中run方法不支持抛出,所以必须捕获处理
  2. 运行时异常(Runtime Exception)
    可以选择打印在控制台,或者设置UncaughtException异常处理器来自定义处理操作

多线程下自定义处理运行时异常

------本文结束感谢阅读------
🐶 您的支持将鼓励我继续创作 🐶