资源、死锁、监测死锁、死锁处理(单应用程序)

资源:变量、对象、网络资源、文件、内存、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.我用的静态代理锁、解锁的动作,目的是监控线程的锁资源信息。

分布式死锁检测逻辑应该一样,只不过监控各个服务线程锁资源、锁等待(单应用的锁和分布式锁的互相锁等等)。考虑情况复杂了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值