Java学习day25:守护线程、死锁、线程生命周期(知识点详解)

声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点+题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!)


往期回顾

Java学习day24:线程的同步和锁(例题+知识点详解)-CSDN博客

Java学习day23:线程构造方法、常用方法(例题+知识点详解)-CSDN博客

Java学习day22:进程和线程、并发并行、线程创建方式(知识点详解)-CSDN博客

 Java学习day25:守护线程、死锁、线程生命周期

一、守护线程

守护线程是用来守护非守护线程的。

那么什么是非守护线程?

非守护线程:

就是平常写的线程,main 主函数是非守护线程
一个应用程序中必须至少一个非守护线程
非守护线程一旦结束,守护线程就会自动消亡

古代皇帝(非守护线程),古代皇帝的妃子(守护线程),一旦皇帝死了,妃子要陪葬!!! 

守护线程依附非守护线程,如果非守护线程消亡,那么守护线程随之消亡。

示例:

class MyThread1 implements Runnable {@Overridepublic void run() {for (int i = 0; i < 1000; i++) {System.out.println("子线程正在执行" + i);}}
}
public class Demo1 {public static void main(String[] args) {//在非守护线程中执行的//启动线程MyThread1 myThread1 = new MyThread1();Thread thread = new Thread(myThread1);//可以将myThread1设置为守护线程。//就会在非守护线程结束De一瞬间,守护线程也会停止执行thread.setDaemon(true);//变成了守护线程了thread.start();for (int i = 0; i < 200; i++) {System.out.println("主线程正在执行" + i);}//在jvm中  main主线程, 还有一个线程 垃圾回收线程//等到main主线程和垃圾回收线程 都结束De时候才守护线程才消亡!!!}
}

真实开发的运用地方:

后台记录操作日志,监控内存,垃圾回收等 都可以使用守护线程。

二、死锁

1.什么是死锁

*死锁*是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于*死锁*状态或系统产生了*死锁*,这些永远在互相等待的进程称为*死锁*线程。

死锁是一种状态,当两个线程互相持有对方的资源的时候,却又不主动释放这个资源的时候。会导致死锁。这两个线程就会僵持住。代码就无法继续执行。

示例1:

你的钥匙丢完了。进不了门?咋办?找开锁公司。
开锁公司说你得给我提供你的身份证原件。我才能给你开锁
你说你得先开门,我的身份证原件在屋里锁着呢。
结果你们两个僵持不下,导致开门这个事推进不了 

 示例2:

线程A  有锁A

线程B  锁B

线程A会等待锁B 的释放

线程B会等待锁A的释放

 开发中禁止使用死锁。 

2.面试常考

 2.1应用场景

并发场景,多线程。线程之间互不相让。在这几种情况下就得借助锁。

加锁的目的是为了线程安全,但是物极必反。尤其是加了锁以后。很容易出现死锁

2.2手写一个死锁

 线程1  有锁1

线程2  锁2

线程1会等待锁2 的释放

线程2会等待锁1的释放

参考:

class DeadLock implements Runnable {private boolean flag;//标记属性private Object obj1;//锁住的对象private Object obj2;//锁住的对象public DeadLock(boolean flag, Object obj1, Object obj2) {this.flag = flag;this.obj1 = obj1;this.obj2 = obj2;}@Overridepublic void run() {//trueif (flag) {//如果设置为true,就让线程1进入到if语句中synchronized (obj1) {//锁住的是obj1对象//线程1持有obj1锁System.out.println(Thread.currentThread().getName() + "拿到了锁1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("等待锁2的释......");//我想在线程1中去使用线程2中的那个锁2 obj2//线程1里面想用obj2锁对象//也走不下去了//线程1也没有释放obj1synchronized (obj2) {System.out.println("123");System.out.println(Thread.currentThread().getName() + "拿到了锁1");}}}if (!flag) {//如果设置为false,就让线程2进入到if语句中synchronized (obj2) {//锁住的是obj2对象//线程2持有obj2这个锁System.out.println(Thread.currentThread().getName() + "拿到了锁2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("等待锁1的释......");//只有obj1释放掉以后,才能在线程2中对obj1加锁//想一个问题,如果obj1锁对象没有被释放,那么下面这个代码//线程2中去锁obj1//在这等着呢 往下走不下去了 线程2没有释放obj2对象synchronized (obj1) {System.out.println("456");System.out.println(Thread.currentThread().getName() + "拿到了锁1");}}}}
}
public class Demo1 {public static void main(String[] args) {Object obj1 = new Object();Object obj2 = new Object();//线程1可以进入到run方法中 if (flag)DeadLock deadLock = new DeadLock(true, obj1, obj2);new Thread(deadLock, "线程1").start();//线程2 可以进入倒run方法中if(!flag)DeadLock deadLock1 = new DeadLock(false, obj1, obj2);new Thread(deadLock1, "线程2").start();}
}

这段代码大家要足够熟悉!两个线程是怎么产生死锁的?线程1锁住了obj1对象的同时,还想去锁住obj2对象,而线程2在锁住了obj2对象的同时,又要去锁住obj1对象,但是线程1没有释放obj1对象,也就导致线程2拿不到obj1对象,也就没法释放obj2对象,线程1也就拿不到obj2对象,于是就产生了死锁。有点绕,大家要想清楚,能够自己独立写出来这段代码。 

三、线程生命周期【面试】

1.五大过程

1)新建当一个Thread类或其子类的对象被声明并创建时。新生的线程对象属于新建状态。
(2)就绪(可运行状态)处于新建状态的线程执行start()方法后,进入线程队列等待CPU时间片,该状态具备了运行的状态,只是没有分配到CPU资源。
(3)运行当就绪的线程分配到CPU资源便进入运行状态,run()方法定义了线程的操作。
(4)阻塞在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时终止自己的的执行,进入阻塞状态。
(5)死亡当线程执行完自己的操作或提前被强制性的终止或出现异常导致结束,会进入死亡状态。

注意:进入阻塞状态后,该线程就需要重新进入就绪状态进行等待获取cpu执行权。

 


以上,就是今天的所有知识点了。死锁问题,是Java知识点中的核心,很多问题都会涉及到,大家不仅要明白原理,还要能够自己手写死锁代码,需要大家得多花点时间,静下心看代码,写代码,多理解。

加油吧,预祝大家变得更强!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/448261.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

leetcode刷题(剑指offer) 103.二叉树的锯齿形层序遍历

103.二叉树的锯齿形层序遍历 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例 1&#xff1a; 输入&#xff1a…

Android矩阵Matrix裁切setRectToRect拉伸Bitmap替代Bitmap.createScaledBitmap缩放,Kotlin

Android矩阵Matrix裁切setRectToRect拉伸Bitmap替代Bitmap.createScaledBitmap缩放&#xff0c;Kotlin class MyImageView : AppCompatImageView {private var mSrcBmp: Bitmap? nullprivate var testIV: ImageView? nullconstructor(ctx: Context, attrs: AttributeSet) :…

Java对象属性设置方式

&#x1f497;wei_shuo的个人主页 &#x1f4ab;wei_shuo的学习社区 &#x1f310;Hello World &#xff01; 对象属性设置方式 直接赋值 SystemMappingCode systemMappingCode new SystemMappingCode();systemMappingCode.setCodeResp(request.getCodeResp());systemMapping…

Unity使用反向遮罩实现镂空shader

实现步骤&#xff1a; 1&#xff0c;创建两个材质球&#xff0c;遮罩层的属性如下&#xff1a; 被遮罩层的属性如下&#xff1a; 2&#xff0c;使用两张image&#xff0c;遮罩层在父节点&#xff0c;被遮罩层在子节点&#xff0c;然后分别添加材质球与镂空图片 实现效果如下&a…

Android.bp入门指南之浅析Android.bp文件

文章目录 Android.bp文件是什么&#xff1f;Android.bp的主要作用模块定义依赖关系构建规则模块属性插件支持模块的可配置性 为什么会引入Android.bp语法例子 Android.bp文件是什么&#xff1f; Android.bp 文件是 Android 构建系统&#xff08;Android Build System&#xff…

JS高级(二)-深入对象、内置构造函数、综合案例

文章目录 1.深入对象1.1创建对象的三种方式1.2构造函数1.3实例成员1.4静态成员 2.内置构造函数2.1 Object2.2 Array2.3显示赠品案例2.4包装类型2.4.1 String2.4.2 Number 3.综合案例——购物车展示 1.深入对象 了解面向对象的基础概念&#xff0c;能够利用构造函数创建对象。 1…

踩坑STM32CubeMX生成Makefile工程无法使用printf(“%f“)

过去一年偶有接触STM32开发时都是使用STM32CubeMX生成Makefile的工程&#xff0c;具体开发环境见配置Clion用于STM32开发&#xff08;Makefile&#xff09;&#xff0c;但没想到今天在使用printf打印输出浮点数时无法正常输出&#xff0c;不仅printf无法使用&#xff0c;其他涉…

SpringFramework实战指南(五)

SpringFramework实战指南(五) 4.3 基于 注解 方式管理 Bean4.3.1 实验一: Bean注解标记和扫描 (IoC)4.3.2 实验二: 组件(Bean)作用域和周期方法注解4.3.3 实验三: Bean属性赋值:引用类型自动装配 (DI)4.3.4 实验四: Bean属性赋值:基本类型属性赋值 (DI)4.3.5 实验五:…

尚硅谷Ajax笔记

一天拿下 介绍二级目录三级目录 b站链接 介绍 ajax优缺点 http node.js下载配置好环境 express框架 切换到项目文件夹&#xff0c;执行下面两条命令 有报错,退出用管理员身份打开 或者再命令提示符用管理员身份打开 npm init --yes npm i express请求 <script>//引…

线上排查问题常用K8s命令

线上排查问题常用K8s命令 1 获取类 kubectl get po&#xff1a;获取默认namespace下节点信息 获取默认Default命名空间下的节点信息 kubectl get ns&#xff1a;获取所有命名空间 kubectl get po -n ziyi&#xff1a;获取指定namespace下的节点信息 kubectl get po -A&#x…

项目安全问题及解决方法------用户密码处理

我们一般来说是不保存原始密码&#xff0c;这样即使被拖库也不会造成用户数据损失&#xff0c;一般来说我们通常会使用 MD5 加密后保存&#xff0c;但是大家对于MD5是使用是否 是正确的呢&#xff1f;MD5 其实不是真正的加密算法。所谓加密算法&#xff0c;是可以使用密钥把明文…

【Uni-App】运行微信小程序时报错routeDone with a webviewId 2 that is not the current page

使用HBuilderX开发微信小程序&#xff0c;运行项目的时有可能会出现routeDone with a webviewId 1 that is not the current page的报错&#xff0c;但不影响运行。如果强迫症介意的话&#xff0c;可以考下面的方法进行修复。 产生原因 由于微信开发者工具的调试基础库处于灰度…