【问题标题】:Can I call a synchronized method that calls a non-synchronized method that calls a synchronized method?我可以调用调用同步方法的非同步方法的同步方法吗?
【发布时间】:2015-04-30 11:20:56
【问题描述】:

在 Java 中,在单个对象和线程中使用 synchronized 关键字。

我可以调用一个调用同步方法的非同步方法的同步方法,而最终同步方法不会阻塞第一个同步方法完成吗?

【问题讨论】:

  • 试试吧……但据我所知答案是没有。
  • AFAIK 我们可以,但死锁的可能性很大
  • 答案是:这取决于同步的组织方式和每个监视器的状态。如果您有单个监视器(锁)并且只有一个线程,那么它不应该有问题,因为在 Java 中的锁是可重入的(线程可以进入同步块中的锁它已经拥有不止一次 - 它只会增加该线程的监视器的计数器)。

标签: java multithreading synchronization java-threads


【解决方案1】:

单对象单线程,没有问题。

你唯一的线程能够获取所有锁,并且由于重入,它可以获取它们多次。

即使我们添加另一个线程,它也可以工作(使用一个对象)。一个线程会获取第一个锁,阻塞第二个线程,然后继续正常执行。

对于多线程和多个对象,答案是“这取决于代码的编写方式”。

【讨论】:

    【解决方案2】:

    无论是否同步,您的代码始终可以调用方法。一个更好的问题是,当你的代码调用它时会发生什么。

    一个如下所示的同步方法:

    synchronized void foobar() {
        doSomething();
    }
    

    其实这只是一种简写方式:

    void foobar() {
        synchronized(this) {
            doSomething();
        }
    }
    

    所以任何关于调用同步方法的问题实际上都是关于执行同步的问题。当您的代码输入 synchronized(this) {...} 时,可能会发生三件事。

    1) 如果this对象没有加锁,那么会以调用线程的名义加锁,线程会执行block中的语句,完成后解锁锁。

    2) 如果this对象已经被调用线程锁定,那么线程将简单地执行块中的语句。

    3) 如果this 对象被某个other 线程锁定,那么调用线程将等待直到另一个线程解锁它,然后它会像情况(1)一样继续。

    您遇到麻烦的唯一方法是您的代码尝试锁定两个不同的锁。然后,如果您的设计没有经过深思熟虑,两个或更多线程可能会死锁,您可以在其他地方阅读到这一点。

    【讨论】:

      【解决方案3】:

      如果一个类同时具有同步和非同步方法,则多个 线程仍然可以访问类的非同步方法。如果你有 不访问您要保护的数据的方法,那么您就不会 需要同步它们。在某些情况下,同步可能会导致命中(或 使用不当甚至死锁)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-20
        • 2020-12-19
        相关资源
        最近更新 更多