oracle.com中有关并发代码的问题,该问题解释了死锁 [英] question about concurrency code from oracle.com that explains Deadlock

查看:66
本文介绍了oracle.com中有关并发代码的问题,该问题解释了死锁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从oracle.com获得了一段代码,它解释了一般的并发性,特别是死锁。该代码来自:



https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html



我努力理解正在进行中,是什么原因导致通过调试和手动运行代码而导致死锁,但无济于事。



如果有人可以中断此流程,我将非常感谢代码并解释代码被阻塞的原因和位置(这样做-我在计算机上运行了它。)



非常感谢

 公共类Deadlock {
静态类Friend {
私有最终字符串名称;
public Friend(String name){
this.name =名称;
}
public String getName(){
返回this.name;
}
公共同步void bow(Friend bower){
System.out.format(%s:%s
+向我鞠躬!%n,
this.name,bower.getName());
bower.bowBack(this);
}
公共同步void bowBack(Friend bower){
System.out.format(%s:%s
+向我鞠躬!%n ,
this.name,bower.getName());
}
}

public static void main(String [] args){
final Friend alphonse =
new Friend( Alphonse);
的最终朋友加斯顿=
新的Friend( Gaston);
new Thread(new Runnable(){
public void run(){alphonse.bow(gaston);}
})。start();
new Thread(new Runnable(){
public void run(){gaston.bow(alphonse);}
})。start();
}
}

运行时-我得到以下输出: / p>

阿方斯:加斯顿向我鞠躬!



加斯顿:阿方斯向我鞠躬!

解决方案

synchronized 关键字隐式意味着在输入方法或块时将获得锁。在方法上使用时,它等效于此:

 公共无效弓(Friend bower){
同步(this){
System.out.format(%s:%s向我鞠躬!%n,this.name,bower.getName());
bower.bowBack(this);
}
}

一次只能有一个线程获得此锁,这意味着由于<$ c $持有锁,一次只能有一个线程同时运行 bow bowBack c>此。



现在请牢记这一点,下面是一个可能的死锁情况:




  • 线程1调用 Alphonse.bow

  • 线程1获得 Alphonse.lock

  • 线程2调用 Gaston.bow

  • 线程2获得 Gaston.lock

  • 线程1调用 Gaston.bowBack

  • 线程1等待 Gaston.lock 被释放,因为线程2仍拥有它

  • 线程2调用 Alphonse.bowBack

  • 线程2等待 Alphonse.lock 被释放,因为线程仍在拥有因此



因此,两个线程都持有一个其他线程需要完成的锁,这是一个死锁!


I got a cross a piece of code from oracle.com which explains concurrency in general and deadlock in particular. the code is from :

https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

I tried hard to understand what is going on and what causes the deadlock here through debugging and manually running the code, but for no avail.

I would be very thankful if someone could break the flow of this code and explain why and where the code gets blocked (which it does - I ran it on my machine).

Thank you very much

public class Deadlock {
    static class Friend {
       private final String name;
       public Friend(String name) {
          this.name = name;
       }
       public String getName() {
          return this.name;
       }
         public synchronized void bow(Friend bower) {
         System.out.format("%s: %s"
            + "  has bowed to me!%n", 
            this.name, bower.getName());
         bower.bowBack(this);
         }
         public synchronized void bowBack(Friend bower) {
            System.out.format("%s: %s"
            + " has bowed back to me!%n",
            this.name, bower.getName());
         }
      }

      public static void main(String[] args) {
         final Friend alphonse =
         new Friend("Alphonse");
         final Friend gaston =
         new Friend("Gaston");
         new Thread(new Runnable() {
           public void run() { alphonse.bow(gaston); }
           }).start();
         new Thread(new Runnable() {
           public void run() { gaston.bow(alphonse); }
           }).start();
      }
}

when running it - I get the following output:

Alphonse: Gaston has bowed to me!

Gaston: Alphonse has bowed to me!

解决方案

The synchronized keyword implicitly means a lock will be acquired upon entering the method or block. When it is used on a method, it is equivalent to this:

public void bow(Friend bower) {
    synchronized (this) {    
        System.out.format("%s: %s has bowed to me!%n", this.name, bower.getName());
        bower.bowBack(this);
     }
 }

Only one thread at a time can acquire this lock, meaning that only one thread can run either bow or bowBack at a time since the lock is held by this.

Now with that in mind, here's one possible deadlock scenario in detail:

  • Thread 1 calls Alphonse.bow
  • Thread 1 acquires Alphonse.lock
  • Thread 2 calls Gaston.bow
  • Thread 2 acquires Gaston.lock
  • Thread 1 calls Gaston.bowBack
  • Thread 1 waits for Gaston.lock to be released because Thread 2 is still owning it
  • Thread 2 calls Alphonse.bowBack
  • Thread 2 waits for Alphonse.lock to be released because Thread is still owning it

Therefore, both threads are holding a lock that the other threads need to complete, and that's a deadlock!

这篇关于oracle.com中有关并发代码的问题,该问题解释了死锁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆