本文介绍了两个线程可以同时访问同步方法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

    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 i run this program i am getting the output as

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

Alphonse: Gaston has bowed to me!Gaston: Alphonse has bowed to me!

那么两个线程可以同时访问一个同步方法吗?

So can two threads access a synchronized method at the same time?

推荐答案

这取决于两个线程试图锁定的对象实例.两个线程无法在同一对象实例上访问相同的synchronized方法.一个将获得锁定,另一个将阻塞,直到第一个线程离开该方法为止.

It depends on what object instance the two threads are trying to lock on. Two threads cannot access the same synchronized method on the same object instance. One will get the lock and the other will block until the first thread leaves the method.

在您的示例中,实例方法在包含它们的对象上同步.在这种情况下,当您调用alphonse.bow(...)时,您将锁定在alphonse对象上. gaston.bow(...)锁定gaston.

In your example, instance methods are synchronized on the object that contains them. In this case, when you call alphonse.bow(...) you are locking on the alphonse object. gaston.bow(...) locks gaston.

有两种方法可以使一个对象的多个实例锁定在同一对象上.

There are a couple of ways that you can get multiple instances of an object to lock on the same object.

  • 您可以将方法设置为staticsynchronized,在这种情况下,它们将锁定类对象本身.每个类加载器只有一个这样的对象.

  • You could make the method be static and synchronized in which case they would lock on the class object itself. There is only one of these objects per class loader.

public static synchronized void bow(Friend bower) {

  • 它们都可以锁定已定义的静态对象.像这样:

  • They could both lock on a defined static object. Something like:

    private static final Object lockObject = new Object();
    ...
    public void bow(Friend bower) {
        synchronized (lockObject) {
            ....
        }
    }
    

  • 或者,如果您不想将其设为静态,则可以传入该对象以进行锁定.
  • 您的输出可能类似于以下内容:

    Your output could be something like the following:

    1. gaston线程(可能)首先启动并调用bow(alphonse)
    2. 这将锁定gaston对象并输出:Gaston: Alphonse has bowed to me!
    3. 它调用alphonse.bowBack(this).
    4. 此调用将锁定alphonse对象并输出:Alphonse: Gaston has bowed back to me!
    5. alphonse.bowBack(this)退出,解锁alphonse对象.
    6. gaston.bow(alphonse)退出,解锁gaston对象.
    7. 然后gaston线程退出.
    8. alphonse线程(可能)接下来开始并调用bow(gaston)
    9. 这将锁定alphonse对象并输出:Alphonse: Gaston has bowed to me!
    10. 它调用gaston.bowBack(this).
    11. 此调用将锁定gaston对象并输出:Gaston: Alphonse has bowed back to me!
    12. gaston.bowBack(this)退出,解锁gaston对象.
    13. alphonse.bow(gaston)退出,解锁alphonse对象.
    1. the gaston thread (may) start first and calls bow(alphonse)
    2. this locks the gaston object and outputs: Gaston: Alphonse has bowed to me!
    3. it calls alphonse.bowBack(this).
    4. this call locks the alphonse object and outputs: Alphonse: Gaston has bowed back to me!
    5. alphonse.bowBack(this) exits, unlocking the alphonse object.
    6. gaston.bow(alphonse) exits, unlocking the gaston object.
    7. then the gaston thread exits.
    8. the alphonse thread (may) start next and calls bow(gaston)
    9. this locks the alphonse object and outputs: Alphonse: Gaston has bowed to me!
    10. it calls gaston.bowBack(this).
    11. this call locks the gaston object and outputs: Gaston: Alphonse has bowed back to me!
    12. gaston.bowBack(this) exits, unlocking the gaston object.
    13. alphonse.bow(gaston) exits, unlocking the alphonse object.

    这可能会以许多不同的顺序发生.即使在以后调用start()方法,alphonse线程也可以首先运行.如果当前正在运行alphonse.bowBack(...),锁将阻止您进入的唯一内容是alphonse.bow(...)的调用.正如@ user988052指出的那样,由于每个线程都锁定自己的对象,然后尝试锁定另一个对象,因此很容易会出现死锁.

    This could happen in a number of different orders. The alphonse thread could run first even though it's start() method gets called at a later time. The only thing that the locks save you from is the calling of alphonse.bow(...) if alphonse.bowBack(...) is currently running. As @user988052 pointed out, because each thread locks their own object and then tries to lock the other, you can easily get a deadlock.

    这篇关于两个线程可以同时访问同步方法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-20 06:09
    查看更多