多线程学习

目录

简单说下你对线程和进程的理解?

那进程和线程有哪些区别呢?

守护线程和用户线程的区别?

什么是线程死锁?

形成死锁的四个必要条件是什么?

我们该如何避免死锁?

死锁避免和死锁预防有啥不同? 


简单说下你对线程和进程的理解?

进程:就是在内存中运行的应用程序,一个进程可以有多个线程,比如微信,qq都是一个进程

线程:就是进程中的具体执行任务,负责当前进程中程序的执行,多个线程可共享数据。

进程 → 火车,线程 → 车厢;线程在进程下行进(单纯的车厢无法运行)

 守护线程和用户线程的区别?

用户 (User) 线程

  • 运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程以及普通自定义线程等都是用户线程

守护 (Daemon) 线程:

  • 运行在后台,为其他前台线程(非守护线程)服务。当所有用户线程都结束运行时,守护线程会随 JVM 一起结束工作.
  •   可见,守护线程是依赖于用户线程,当所有用户线程都退出了,守护线程也就会退出,典型的守护线程如垃圾回收线程
  •   而用户线程是独立存在的,不会因为其他用户线程退出而退出。

二者其实基本上是一样的。唯一的区别在于JVM何时离开。

用户线程:当存在任何一个用户线程未离开,JVM是不会离开的。

守护线程:如果只剩下守护线程未离开,JVM是可以离开的。

  • 注意: 默认情况下启动的线程是用户线程,通过setDaemon(true)将线程设置成守护线程,但必须在start()方法前执行,否则会抛出 IllegalThreadStateException 异常
  • 在守护线程中产生的新线程也是守护线程
  • 守护 (Daemon) 线程中不能依靠 finally 块的内容来确保执行关闭或清理资源的逻辑。因为我们上面也说过了一旦所有用户线程都结束运行,守护线程会随 JVM 一起结束工作,所以守护 (Daemon) 线程中的 finally 语句块可能无法被执行。

什么是线程死锁? 

 死锁是指两个或多个进程(线程)在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,程序就会永远卡在那里

 

// 示例来自《并发编程之美》
public class DeadLockDemo {
    private static Object resource1 = new Object();//资源 1
    private static Object resource2 = new Object();//资源 2

    public static void main(String[] args) {
        new Thread(() -> {
            synchronized (resource1) {
                System.out.println(Thread.currentThread() + "get resource1");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource2");
                synchronized (resource2) {
                    System.out.println(Thread.currentThread() + "get resource2");
                }
            }
        }, "线程 1").start();

        new Thread(() -> {
            synchronized (resource2) {
                System.out.println(Thread.currentThread() + "get resource2");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread() + "waiting get resource1");
                synchronized (resource1) {
                    System.out.println(Thread.currentThread() + "get resource1");
                }
            }
        }, "线程 2").start();
    }
}

形成死锁的四个必要条件是什么?

互斥: 某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程访问结束。
占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放。等待其他进程释放该资源。
不可抢占: 别人已经占有了某项资源,你不能因为自己也需要该资源,就去把别人的资源抢过来。
循环等待: 存在一个进程链,使得每个进程都占有下一个进程所需的至少一种资源。头尾相接的循环等待资源关系

 我们该如何避免死锁?

死锁预防:----- 确保系统永远不会进入死锁状态

从四个必要条件下手 

  1. 打破互斥条件:改造独占性资源为虚拟资源,不过大部分资源已无法改造,一般从另外仨下手。
  2. 破坏“占有且等待”条件:一次性申请全部资源条件
  3. 破坏不可抢占:/满足两个剩下一个未满足,则释放手里的资源条件
  4. 破坏循环等待:对资源进行编码,当一个进程占有编号为i的资源时,那么它下一次申请资源只能申请编号大于i的资源

死锁避免和死锁预防有啥不同? 

 死锁预防,至少破坏四个必要条件之一,严格的防止死锁的出现;死锁避免就是没有那么严格的限制产生死锁的必要条件的存在,即使死锁的必要条件存在,也不一定发生死锁,死锁避免是在系统运行过程中利用额外的检验信息,在分配资源时判断是否会出现死锁,只在不会出现死锁的情况下才分配资源。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值