zoukankan      html  css  js  c++  java
  • 理解Deadlock

    问:为啥以下代码会产生死锁

    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();
        }
    }
    

    答:

    In Java, each Object provides the ability for a Thread to synchronize, or lock, on it. When a method is synchronized, the method uses its object instance as the lock. In your example, the methods bow and bowBack are both synchronized, and both are in the same class Friend. This means that any Thread executing these methods will synchronize on a Friend instance as its lock.

    A sequence of events which will cause a deadlock is:

    1. The first Thread started calls alphonse.bow(gaston), which is synchronized on the alphonse Friend object. This means the Thread must acquire the lock from this object.
    2. The second Thread started calls gaston.bow(alphonse), which is synchronized on the gastonFriend object. This means the Thread must acquire the lock from this object.
    3. The first thread started now calls bowback and waits for the lock on gaston to be released.
    4. The second thread started now calls bowback and waits for the lock on alphonse to be released.

    To show the sequence of events in much more detail:

    1. main() begins to execute in the main Therad (call it Thread #1), creating two Friendinstances. So far, so good.
    2. The main Thread starts its first new Thread (call it Thread #2) with the code new Thread(new Runnable() { .... Thread #2 calls alphonse.bow(gaston), which is synchronized on the alphonse Friend object. Thread #2 thus acquires the "lock" for the alphonse object and enters the bow method.
    3. A time slice occurs here and the original Thread gets a chance to do more processing.
    4. The main Thread starts a second new Thread (call it Thread #3), just like the first one. Thread #3 calls gaston.bow(alphonse), which is synchronized on the gaston Friend object. Since no-one has yet acquired the "lock" for the gaston object instance, Thread #3 successfully acquires this lock and enters the bow method.
    5. A time slice occurs here and Thread #2 gets a chance to do more processing.
    6. Thread #2 now calls bower.bowBack(this); with bower being a reference to the instance for gaston. This is the logical equivalent of a call of gaston.bowBack(alphonse). Thus, this method is synchronized on the gaston instance. The lock for this object has already been acquired and is held by another Thread (Thread #3). Thus, Thread #2 has to wait for the lock on gastonto be released. The Thread is put into a waiting state, allowing Thread #3 to execute further.
    7. Thread #3 now calls bowback, which in this instance is logically the same as the call alphonse.bowBack(gaston). To do this, it needs to acquire the lock for the alphonse instance, but this lock is held by Thread #2. This Thread is now put into a waiting state.

    And you are now in a position where neither Thread can execute. Both Thread #2 and Thread #3 are waiting for a lock to be released. But neither lock can be released without a Thread making progress. But neither thread can make progress without a lock being released.

    Thus: Deadlock!

    Deadlocks very often depend on a specific sequence of events occurring, which can make then difficult to debug since they can be difficult to reproduce.

    原文链接:https://stackoverflow.com/questions/749641/how-does-synchronized-work-in-java

  • 相关阅读:
    js添加获取删除cookie
    华为Scan Kit二维码扫描
    Android中使用抖动动画吸引来用户注意-属性动画
    material_dialogs 动画弹框
    flutter 通过widget自定义toast,提示信息
    flutter 通过用户信息配置路由拦截 shared_preferences
    fluterr shared_preferences 存储用户信息 MissingPluginException(No implementation found for method getAll on channel
    Android Scroller及实际使用
    Antd Tree简单使用
    iOS开发--runtime常用API
  • 原文地址:https://www.cnblogs.com/season2009/p/8778073.html
Copyright © 2011-2022 走看看