-
Java连载110-类锁、死锁、守护线程
一、类锁
1.类只有一个,所以锁是类级别的,只有一个
package com.bjpowernode.java_learning; public class D110_1_ClassLock { public static void main(String[] args) throws Exception{ Thread t1 = new Thread(new Processor110()); Thread t2 = new Thread(new Processor110()); t1.setName("t1"); t2.setName("t2"); t1.start(); //延迟,保证t1先执行 Thread.sleep(1000); //下面的方法没有等t1结束,因为这个方法不函数有锁。如果这个方法加上synchronized就会等着t1结束。 t2.start(); //即使是实例化对象了,这个类锁也是有效的,跟对象也没有,底层用的是类锁 } } class Processor110 implements Runnable{ public void run() { if("t1".equals(Thread.currentThread().getName())){ MyClass110.m1(); } if("t2".equals(Thread.currentThread().getName())){ MyClass110.m2(); } } } class MyClass110{ //synchronized添加到静态方法上,线程执行方法的时候会找类锁。 public synchronized static void m1() { try { Thread.sleep(10000); }catch (Exception e) { e.printStackTrace(); } System.out.println("m1......"); } public static void m2() { System.out.println("m2......"); } }
二、死锁现象
package com.bjpowernode.java_learning; public class D110_2_DeadLock { public static void main(String[] args) throws Exception{ Object o1 = new Object(); Object o2 = new Object(); Thread t1 = new Thread(new T110(o1,o2)); Thread t2 = new Thread(new T111(o1,o2)); t1.start(); t2.start(); } } class T110 implements Runnable{ Object o1; Object o2; T110(Object o1,Object o2){ this.o1 = o1; this.o2 = o2; } public void run() { synchronized(o1) { try { Thread.sleep(500); }catch(Exception e) { e.printStackTrace(); } synchronized(o2) { System.out.println("没有死锁"); } } } } class T111 implements Runnable{ Object o1; Object o2; T111(Object o1,Object o2){ this.o1 = o1; this.o2 = o2; } public void run() { synchronized(o2) { try { Thread.sleep(500); }catch(Exception e) { e.printStackTrace(); } synchronized(o1) { System.out.println("没有死锁"); } } } }
两个锁死锁了,没办法打印出来“没有死锁”这几个字了。
三、守护线程和用户线程
1.用户线程:以上讲的都是守护线程。
2.守护线程:其他所有的用户线程结束,则守护线程退出;守护线程一般都是无限执行的;守护线程是这样的,所有的用户线程结束生命周期,守护线程才会结束生命周期,只有有一个用户线程存在,那么守护线程就不会结束,例如:java中著名的垃圾回收器就是一个守护线程,只有应用程序中的所有线程都结束,他才会结束。
package com.bjpowernode.java_learning; public class D110_3_DaemonThread { public static void main(String[] args) { Thread t1 = new Processer110_1(); t1.setName("守护线程"); //将t1这个用户线程修改为守护线程 t1.setDaemon(true); t1.start(); try { Thread.sleep(1000); }catch(Exception e) { e.printStackTrace(); } for(int i=0;i<10;i++) { System.out.println(Thread.currentThread().getName()+"-->"+i); } } } class Processer110_1 extends Thread{ public void run() { while(true) { System.out.println(Thread.currentThread().getName()+"-->"); try { Thread.sleep(500); }catch(Exception e) { e.printStackTrace(); } } } }
可以看出来mainà9之后不会再进行打印打印守护线程,守护线程直接停止了。
四、源码:
D110_1_ClassLock.java
D110_2_DeadLock.java
D110_3_DaemonThread.java
https://github.com/ruigege66/Java/blob/master/D110_1_ClassLock.java
https://github.com/ruigege66/Java/blob/master/D110_2_DeadLock.java
https://github.com/ruigege66/Java/blob/master/D110_3_DaemonThread.java
出 处:https://www.cnblogs.com/ruigege0000/p/12723605.html
最新更新
带有参数的装饰器
类装饰器
django中的auth模块与admin后台管理
python的日期处理
字符串常用方法
基本数据类型概述
python-map()函数基本用法
python带你实现任意下载AcFun视频数据~
bbs项目之注册功能
变量的定义和使用
三大常用数据库事务详解之三:事务运行
三大常用关系型数据库事务详解之二:基
三大关系型数据库事务详解之一:基本概
MongoDB常用命令(2)
MongoDB基本介绍与安装(1)
SQLServer触发器调用JavaWeb接口
SQL Server索引的原理深入解析
SqlServer2016模糊匹配的三种方式及效率问题
SQL中Truncate的用法
sqlserver 多表关联时在where语句中慎用tri
VB.NET中如何快速访问注册表
ASP.NET中图象处理过程详解
Vue(1)Vue安装与使用
JavaScript 语言入门
js将一段字符串的首字母转成大写
纯原生html编写的h5视频播放器
H5仿原生app短信验证码vue2.0组件附源码地
TypeScript(4)接口
TypeScript(3)基础类型
TypeScript(2)WebStorm自动编译TypeScript配置