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

Java多线程死锁的出现和解决方案

电脑杂谈  发布时间:2020-03-20 17:10:43  来源:网络整理

c++ 线程死锁_线程死锁_线程死锁

什么是死锁?

死锁是一种情况,其中多个线程同时被阻塞,并且其中一个或所有线程都在等待释放资源. 由于线程被无限期阻塞,因此程序无法正常运行. 从视觉上讲,这是: 一件宝藏需要打开两个钥匙,并且两个人同时进入. 他们每个人都有一把钥匙,但是双方都等着对方交出钥匙来打开宝藏. 没有人释放自己的钥匙. 这样,两个人就陷入僵局,直到开发人员发现这种情况为止.

死锁的根本原因是不正确地使用了“ synchronized”关键字来管理对特定对象的线程访问. “ synchronized”关键字的作用是确保一次块仅允许一个线程执行特定代码,因此,被允许执行的线程必须首先具有对该变量或对象的独占访问权限. 当线程访问该对象时,该线程将锁定该对象,并且此锁将导致要访问同一对象的其他线程被阻塞,直到第一个线程释放它放置在该对象上的锁为止.

线程死锁_线程死锁_c++ 线程死锁

如果您对同步了解不多,请单击此处

例如

大多数死锁发生在您不知道的时候. 让我们举个例子看看什么是僵局.

c++ 线程死锁_线程死锁_线程死锁

1. 同步嵌套.

The

synchronized关键字可以确保当多个线程访问synced方法时确保同步. 即,当线程A访问此方法时,线程B也访问此方法. 这时,线程B将阻塞. 等待线程A执行,然后才能访问它. 在这里线程死锁,我们将使用由sync持有的同步锁. 有关详细信息,请查看代码:

c++ 线程死锁_线程死锁_线程死锁

//首先我们先定义两个final的对象锁.可以看做是共有的资源.
 final Object lockA = new Object();
 final Object lockB = new Object();
//生产者A
 class ProductThreadA implements Runnable{
   @Override
   public void run() {
//这里一定要让线程睡一会儿来模拟处理数据 ,要不然的话死锁的现象不会那么的明显.这里就是同步语句块里面,首先获得对象锁lockA,然后执行一些代码,随后我们需要对象锁lockB去执行另外一些代码.
     synchronized (lockA){
     //这里一个log日志
       Log.e("CHAO","ThreadA lock lockA");
       try {
         Thread.sleep(2000);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       synchronized (lockB){
        //这里一个log日志
         Log.e("CHAO","ThreadA lock lockB");
         try {
           Thread.sleep(2000);
         } catch (InterruptedException e) {
           e.printStackTrace();
         }
       }
     }
   }
 }
 //生产者B
 class ProductThreadB implements Runnable{
 //我们生产的顺序真好好生产者A相反,我们首先需要对象锁lockB,然后需要对象锁lockA.
   @Override
   public void run() {
     synchronized (lockB){
      //这里一个log日志
       Log.e("CHAO","ThreadB lock lockB");
       try {
         Thread.sleep(2000);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       synchronized (lockA){
        //这里一个log日志
         Log.e("CHAO","ThreadB lock lockA");
         try {
           Thread.sleep(2000);
         } catch (InterruptedException e) {
           e.printStackTrace();
         }
       }
     }
   }
 }
 //这里运行线程
ProductThreadA productThreadA = new ProductThreadA();
ProductThreadB productThreadB = new ProductThreadB();
   Thread threadA = new Thread(productThreadA);
   Thread threadB = new Thread(productThreadB);
   threadA.start();
   threadB.start();

分析,当线程A开始执行run方法时,它将首先保持对象锁localA线程死锁,然后休眠2秒钟. 这时,threadB也开始执行run方法,该方法持有localB对象锁. 当threadA运行时找到第二种同步方法时,无法使用localB的对象锁(threadB没有释放localB锁),threadA在这里停止以等待localB锁. 然后线程B还执行第二种同步方法以访问localA对象锁. 发现还没有释放localA(线程A没有释放localA锁),并且threadB也在这里停止以等待localA锁被释放. 这样,两个线程都无法继续执行并进入死锁状态. 查看结果: p>

10-20 14:54:39.940 18162-18178/? E/CHAO: ThreadA lock lockA
10-20 14:54:39.940 18162-18179/? E/CHAO: ThreadB lock lockB

当没有死锁时,应该打印四个日志,并且在这里明显出现死锁现象.

线程死锁_c++ 线程死锁_线程死锁

死锁的原因

当我们了解发生死锁的情况以及什么是死锁时,我们应该在编写代码时尝试避免这种误解. 死锁必须同时满足以下四个条件,只要其中之一满足任何条件,就不会发生死锁.

解决方案陷入僵局

说实话,为避免死锁,编写自己的代码时必须注意. 这里是对其他人的解决方案的参考,但是我对这些解决方案并不了解,它们太模糊并且没有具体示例.

以上是本文的全部内容. 希望对大家的学习有所帮助. 我也希望每个人都支持该脚本主页.


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

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

      每日福利
      热点图片
      拼命载入中...