资源:变量、对象、网络资源、文件、内存、cpu等等
(应用层或者会话层 资源)
统一资源限定符:[scheme:][//authority][path][?query][#fragment]
authority 可以表示: [user-info@]host[:port]
比如: file:F:\ideawork\client\pom.xml (本地文件,中间的“\”符号要用File.separator 因为不同系统文件路径符号不同),网络文件就要服务器装ftp,超文本协议就可以用http://www.baidu.com
URI:对统一资源限定符进行封装,可以解析出相关内容信息
URL: 指向一个资源,然后可以拿网络连接、输入、输出流
比如:访问网站, openUrlConnection 拿到URLConnection 然后通过连接进行资源访问。
或者jdbc:mysql://192.168.43.3:3306/test mysql数据库连接资源 ,他不能通过URL打开,只能通过DriverManager去拿连接(具体的Driver需要数据库厂商提供)。
(传输层网络资源)
socket 分为BIO (阻塞) NIO(异步,通过selector进行绑定);都需要设置超时时间(防止dos攻击)、窗口大小(太小了传输慢(一个周期内的数据量少),太大了占内存资源)等.
BIO 也就是对方不给你发消息,你线程就阻塞了,(socket.getinputstream.read)
注意区分:窗口大小和read里面接收的byte[] 不是一回事,窗口大小是设置网卡哪里的缓存大小,read里面的byte[]是你程序读取缓存的大小。
NIO 通过 selector监听已注册通道的状态(select方法),channel 进行selector注册,绑定一个参数(比如 服务通道绑定accpet)
死锁:线程a拿了A资源的锁,然后b线程拿了B资源的锁,再都没释放的情况下,a去申请B资源的锁,等待b线程释放,然后b线程去申请拿A资源的锁,等待a线程释放,此时就是死锁了
或者N个线程一起锁了,比如 a拿了A,b拿了B ,c拿了C,d拿了D,然后a申请B,b申请C,c申请D,d申请A, 造成死锁。
原理简单,把这个等待可以看成单链,因为每个线程只能等待一个资源,而资源又指向一个线程。类似单链
然后只要单链中有一个或者多个回路,也就是其中某个线程指向了他上层线程,那就完犊子了。
1.如何预防:资源锁顺序拿,比如A\B\C三个资源,a\b\c三个线程,然后a要拿A和B
b要拿B和C c要拿C和A ,只需要给资源排序,拿资源顺序必须按照 A\B\C的顺序拿
这时候c线程 是拿A和C 这时候A被锁了,等a线程;
然后 b线程完了之后,释放B和C资源,a线程继续跑,释放完A之后,c线程可以拿A和C执行了。
2.资源太多不好排序,那就资源分类, 比如 ABC 是一类 DEF 是一类,然后给类排序
然后按顺序拿类的锁,再去锁需要的单个或多个资源,然后释放类的锁。(类似于表级锁)
如果类也不好排序,那就直接一个大锁,拿完大锁,拿类锁,释放大锁,拿资源锁,释放类锁(类似于全局锁)
3.死锁检测:只能检测自己系统的,别人系统监测不了,所以调用别人系统的时候要设置超时时间,然后会有数据问题,就有了分布式事务以及最终一致性解决方案 以及定时任务调度。
监测:1.jvm工具,拉线程栈分析 不太会,后面再说。
2.程序自检
1.代理锁的动作,锁成功的时候记录线程当前的锁资源,解锁的时候释放掉当前资源,多个锁按顺序存、释放 使用栈。
2.子线程再等待前记录blocker - (等待的资源 AQS会自动记录 )(统一用底层是LockSupper实现的锁 - java自带的AQS) 不能用关键字锁,不会有blocker
3.每个线程定义一个栈,把已经拿到的锁资源压栈,目的:保证锁的顺序拿、顺序释放。
4.开启守护线程,循环监测锁等待的线程的blocker,构建链表 、 查看是否有回路有就结束线程,手动释放锁资源
相关项目https://github.com/liukeling/Demos 检测代码、处理逻辑在demo里面
注意点:
1. 锁blocker对象 sync 在拿了资源锁后维护线程目前的资源要通过反射去拿他的sync与blocker的sync做比较判断
2.强制释放锁资源: release 方法、设置当前线程为要执行的线程(反射)。循环构建树、死锁检查、处理的时候要注意死循环问题
3.我目前检测到死锁的处理方式是停止树最高层的线程,以及释放他的资源(倒过来的,树根为1,往下找,层数越高)这样影响较小,注意点:线程stop之后要重新维护下自定义的线程资源
4.我用的静态代理锁、解锁的动作,目的是监控线程的锁资源信息。
分布式死锁检测逻辑应该一样,只不过监控各个服务线程锁资源、锁等待(单应用的锁和分布式锁的互相锁等等)。考虑情况复杂了。