Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
557 views
in Technique[技术] by (71.8m points)

concurrency - Question About Deadlock Situation in Java

I'm learning about deadlocks in Java, and there's this sample code from Sun's official tutorial:

Alphonse and Gaston are friends, and great believers in courtesy. A strict rule of courtesy is that when you bow to a friend, you must remain bowed until your friend has a chance to return the bow. Unfortunately, this rule does not account for the possibility that two friends might bow to each other at the same time.

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

Here's Sun's explanation:

When Deadlock runs, it's extremely likely that both threads will block when they attempt to invoke bowBack. Neither block will ever end, because each thread is waiting for the other to exit bow.

I don't quite seem to follow. When alphonse.bow(gaston) runs, the bow method is locked. So now it'll first print "Gaston has bowed to me!". Then it'll go on and call bowBack, and locks bowBack as well. How can this cause a deadlock? Am I misunderstanding what happens when a synchronized method is called?

If someone can give me a easy explanation, thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

One important point to note is that it is not methods which are locked but object instances.

When you call alphonse.bow(gaston), it tries to acquire the lock on alphonse. Once it has the lock, it prints a message, then calls gaston.bowBack(alphonse). At this point, it tries to acquire the lock on gaston. Once it has the lock, it prints a message, then releases the lock, and finally the lock on alphonse is released.

In deadlock, the locks are acquired in such an order that there's no way for either thread to proceed.

  • Thread 1: acquires lock on alphonse
  • Thread 2: acquires lock on gaston
  • Thread 1: prints message
  • Thread 1: tries to acquire lock on gaston - can't, because Thread 2 already has it.
  • Thread 2: prints message
  • Thread 2: tries to acquire lock on alphonse - can't, because Thread 1 already has it.

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...