b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

多线程死锁的预防和避免&开发中的注意事项

电脑杂谈  发布时间:2019-08-12 23:05:48  来源:网络整理

多线程如何避免死锁_避免死锁_c 线程死锁

在一组进程发生死锁的现象下,这组死锁进程中的每一个进程,都在等待另一个死锁进程所占据的资源。或者说每位进程所等待的风波是该组中其它进程释放所占据的资源。

举个实例:因为此时有一个线程A,根据先锁a再获得锁b的的次序获得锁,而在此同时又有另外一个线程B,根据先锁b再锁a的次序获得锁。这时线程A获取了锁a,线程B获取了锁b,线程A想要继续获取锁b,所以锁b被线程B占有;线程B想要继续获取锁a,所以锁a被线程A占有,这种线程A和线程B都在等待对方释放资源,也就是形成了资源获取的重构多线程如何避免死锁,使得死锁的发生。

形成死锁必须同样满足以上四个条件,只要其中任一条件不设立,死锁就不会发生。

互斥条件:进程要求对所分配的资源进行排它性使用,即在一段时间内,某 资源仅为一个进程所占据。如果此时若有这些进程请求该资源,则请求进程只能等待,直至占有该资源的进程用毕释放。

请求和维持条件:进程已经维持了起码一个资源,但又提出了新的资源请求,而该资源已被这些进程占据,此时请求进程被阻塞,但对自己已获得的资源保持不放。

不占领条件:进程已获得的资源在未使用完毕之前,不能被占领,即只能在进程使用完时自己释放。

循环等待条件:在发生死锁时,必定存在一个进程—资源的循环等待链,即进程集合{Pl, P2, ..., pn},P0正在等待一个P1占用的资源,其中Pi等待的资源被P(i+1)占据(i=, 1, ..., n-1),Pn等待的资源被P占有。

预防死锁。这是一种较简单和直观的预先预防办法。该方式是通过增设这些限制条件,去破坏造成死锁的四个必要条件中的一个或几个来预防产生死锁。预防死锁是一种易实现的方式,已被广泛使用。

避免死锁_c 线程死锁_多线程如何避免死锁

避免死锁。同样是属于事先预防策略,但它并不是事先采取这些限制措施,去破坏造成死锁的四个必要条件,而是在资源的动态分配过程中,用某些方式避免系统步入不安全状况,因而可以防止发生死锁。

检测死锁。这种方式无须事先采取任何限性制措施,禁止进程在运行过程中发生死锁。但可通过测试机构及时地检测出死锁的发生,然后实行适当的举措,把进程从死锁中解脱出来。

解除死锁。当检测到功能中已发生死锁时,就实行对应的举措,把进程从死锁中解脱出来。常用的方式是撤消一些进程,回收这些的资源,将资源分配给已处于阻塞状况的进程,使其能继续运行。

(1)最理想的状况:两个锁的申请就没有发生交叉,防止了死锁的可能性,这是最理性的现象,因为锁没有发生交叉。如果希望如此感性,就不需要讨论死锁了。

(2)最好是能够防止在一个同步方式中读取其他对象的延时方式和同步方式。一旦我们在一个同步方式中,如果说在一个锁的保护的范围中,读取了其他对象的方式时,就要特别的谨慎:

(3)以确认的次序获得锁,破坏“循环等待条件”。针对多线程需要共同访问的资源进行线性排序,并赋于不同的序号,应当每一个线程必须根据序号递增的次序请求资源。采用这样思路,怎么排序就显得很重要。通常以大多数线程需要的锁如果资源的相继顺序进行排序。

(4)超时放弃,锁持有的时间加一个期限,破坏“请求和维持条件”。当使用synchronized关键词提供的集成锁时,只要线程没有获得锁,所以就能始终等待下去,但是Lock接口提供了boolean tryLock(long time, TimeUnit unit) throws InterruptedException方法,该方式可以根据固定时长等待锁,所以线程可以在获取锁超时之后,主动释放之前已经获得的一切的锁。通过这些方法,也可以很有效地防止死锁。

(5)使用事宜时,尽量延长事务的思维处理过程,及早提交或回滚事务; (细化处理思路,执行一段逻辑后便回滚或者填写,然后再执行其他观点,防止开启事务以后,等待用户输入,如果读取服务接口等耗时的操作)

c 线程死锁_多线程如何避免死锁_避免死锁

Jstack命令

jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。

Jstack工具可以用来生成java虚拟机当前时刻的线程快照。线程快照是目前java虚拟机内每一条线程正在执行的方式堆栈的集合,生成线程快照的主要动机是定位线程出现长时间停顿的因素,如线程间死锁、死循环、请求外部资源造成的长时间等待等。 线程出现停顿的时候借助jstack来察看各个线程的调用堆栈,就可以明白没有响应的线程到底在后台做多少大事,如果等待多少资源。

首先,我们通过jps确定目前执行任务的进程号:

jonny@~$ jps
597
1370 JConsole
1362 AppMain
1421 Jps
1361 Launcher

可以确认任务进程号是1362,然后执行jstack命令察看目前进程堆栈信息:

jonny@~$ jstack -F 1362
Attaching to process ID 1362, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 23.21-b01
Deadlock Detection:
Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock Monitor@0x00007fea1900f6b8 (Object@0x00000007efa684c8, a java/lang/Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock Monitor@0x00007fea1900ceb0 (Object@0x00000007efa684d8, a java/lang/Object),
  which is held by "Thread-1"
Found a total of 1 deadlock.

可以看见,进程的确存在死锁,两个线程分别在等待对方持有的Object对象

避免死锁_c 线程死锁_多线程如何避免死锁

JConsole工具

Jconsole是JDK自带的监控工具,在JDK/bin目录下可以寻找。它用来联接正在运行的本地或者远程的JVM,对运行在Java应用程序的资源消耗和外观进行监控,并画出较多的图表,提供超强的可视化页面。而且自身占用的服务器内存很小,甚至可以说几乎不消耗。

我们在命令行中敲入jconsole命令,会自动弹出以上对话框,选择进程1362,并点击“链接”

新建连接

进入所检测的进程后,选择“线程”选项卡,并点击“检查死锁”

检测死锁

c 线程死锁_避免死锁_多线程如何避免死锁

可以看见以上镜头:

可以看见进程中存在死锁。

死锁检测硬件检测出模块中发生了死锁,可以通过:

抢占资源。从一个或多个进程中占领足够人数的资源,分配给死锁进程,以解除死锁状态。

终止(或撤销)进程。终止(或撤销)功能中的一个或多个死锁进程,直至打破循环环路,使功能从死锁状态中解脱出来。

其他是操作系统层面的操作,我们的项目中并不会有死锁检测硬件在扫描我们的线程多线程如何避免死锁,所以真的不幸发生了死锁,我想重启大法或许是最简单有效的。

参考资料:


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-119023-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...