加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 两个线程可以同时访问同步方法吗?

发布时间:2020-12-14 05:04:41 所属栏目:Java 来源:网络整理
导读: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"
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",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();
    }
}

当我运行这个程序,我得到的输出

阿方:加斯顿对我鞠躬
加斯顿:阿方便对我鞠躬

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

解决方法

Can two threads access a synchronized method at the same time?

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

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

>您可以使该方法为静态和同步,在这种情况下,它们将锁定在类对象本身上.每个类加载器只有这些对象之一.

public static synchronized void bow(Friend bower) {

>他们都可以锁定一个定义的静态对象.就像是:

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

>或者你可以传递对象来锁定,如果你不想让它静态.

您的输出可能类似于以下内容:

> gaston线程(可能)首先启动并调用bow(alphonse)
>这会锁定gaston对象并输出:Gaston:Alphonse已经对我鞠躬了!
它调用alphonse.bowBack(this).
>这个调用锁定alphonse对象并输出:Alphonse:Gaston已经回到了我!
> alphonse.bowBack(this)退出,解锁alphonse对象.
> gaston.bow(alphonse)退出,解锁gaston对象.
>然后gaston线程退出.
> alphonse线程(可能)接下来开始,并调用bow(gaston)
>这会锁定alphonse对象并输出:Alphonse:Gaston已经对我鞠躬了!
它叫做gaston.bowBack(这个).
>这个调用锁定gaston对象并输出:Gaston:Alphonse已经回到了我!
> gaston.bowBack(this)退出,解锁gaston对象.
> alphonse.bow(gaston)退出,解锁对象.

这可能发生在许多不同的订单.即使start()方法在以后调用也可以先运行a??lphonse线程.如果alphonse.bowBack(…)当前正在运行,锁定保存的唯??一方法是调用alphonse.bow(…).正如@ user988052所指出的,因为每个线程都锁定自己的对象,然后尝试锁定另一个,你可以很容易地得到一个死锁.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读