当前位置: 首页 > 知识库问答 >
问题:

死锁是每个方法还是每个类发生?

闻人树
2023-03-14

想象一下,我用几个同步的方法< code>First了类。当线程< code >首先锁定类时,它是锁定每个方法还是每个类?例如,下面的代码会发生死锁吗?

public class DeadLockQuestion {

    public static class First{
        public synchronized void a(){

        }
        public synchronized void b(){

        }
        public synchronized void c(){

        }   
        public synchronized void d(){

        }
        public synchronized void e(){

        }       
    }

    public static void main(String... args){
        First f = new First();

        //This code is run in Thread 1
        f.a();
        // End
        //This code is run in Thread 2 simultanously
        f.b();
        //End
        // We have also Threads 3 & 4 & 5 that invoke c,d and e simultanously

    }

}

共有3个答案

须巴英
2023-03-14

要单独锁定每个方法,请在每个方法中使用一个synchronized块,并锁定不同的对象。

如果你在类中已经有了一个合适的(并且应该是最终的以防止潜在的问题)对象,你可以使用它。如果没有创建< code >私有最终对象aLock = new Object();然后锁定,例如:

private final Object aLock = new Object();

public void a() {
    synchronized(aLock) {
         // Do stuff that needs the lock
    }
    // do stuff that doesn't need the lock
}

只要你需要,就一直保持锁定,但不要太久。

裴卓君
2023-03-14

死锁发生在线程上,而不是方法或类上。

死锁的线程也持有锁,但是在这种情况下,不可能判断哪些锁,因为您没有演示实际的死锁场景(如果两个线程调用f的同步方法,一个通过,另一个等待;死锁至少需要两个锁)。

施选
2023-03-14

Java有两个锁。一个是对象锁。另一个是类锁。对象锁只锁定同步的非静态函数。类锁只锁定同步的静态函数。对你来说,它是对象f上的对象锁。所以所有同步的非静态函数都被锁定为对象f。由于所有线程都使用相同的对象f,一次只能有一个线程能够访问您的非静态函数a()、b()、…。在这里阅读更多

does deadlock happen for the following code?

不,这不会发生在你的情况下。因为当一个线程持有锁时,其他线程无法进入同步函数死锁是由资源造成的
您只有一个资源,即Object(对象)f。这里没有死锁的意义,因为类First不会锁定另一个对象,也不会发生循环锁定。死锁需要循环锁!

一些信息:

  1. java中的同步保证没有两个线程可以同时或并发地执行需要相同锁的同步方法
  2. synchronized关键字只能与方法和代码块一起使用。这些方法或块可以是静态的,也可以是非静态的
  3. 当一个线程进入java同步方法或块时,它会获得一个锁,当它离开java同步方法或者块时,就会释放锁。即使线程在完成后或由于任何错误或异常而离开同步方法,也会释放锁
  4. 静态同步方法和非静态同步方法都可能同时或并发运行,因为它们锁定在不同的对象上
    此处和此处的有用来源
 类似资料:
  • 问题内容: 我必须对一个大型Java项目做一个一般性的说明,但是我对它的了解很少,我想知道是否有确定以下内容的准则: 每个包有多少个类可以被认为是正确的,低或高的(这个项目每个包有3.89个类,对我来说似乎太小了), 每个类有多少种方法?(该项目每个类有6.54个方法… 每个方法的行数?(此项目每种方法大约有7行(对我来说似乎不错,也许有点低)) 我应该指出,这个问题仅涉及体积。我有很多来自质量工

  • 我的理解是,在Tomcat中,每个请求将占用一个Java/(因此也是OS)线程。 想象一下,我有一个应用程序,有很多长时间运行的请求(例如一个有多个玩家的扑克游戏),涉及游戏内聊天和AJAX长轮询等。 有没有办法更改我的webapp的tomcat配置/体系结构,这样我就不会对每个请求使用线程,而是“截获”请求和响应,这样它们就可以作为队列的一部分进行处理?

  • 我用的是Kafka0.8.2。正如文件所说: batch.num.messages指定: 使用异步模式时要在一批中发送的消息数。生产者将等待该数量的消息准备好发送或排队。缓冲器已达到最大毫秒。 和请求。必修的。acks控制代理对请求的确认。 我想知道Kafka经纪人如何发送这个确认,它是否发送批次确认字符,还是每个单独的消息?

  • 问题内容: 我有一个客户端服务器程序在服务器端使用套接字,并且读写发生在这种方式 同样在cilent(android)方面… 问题是,建立连接后,程序会卡住它们,没有错误,也没有异常。停下来 问题答案: 这是一个死锁,您必须首先创建并刷新ObjectOutputStream。这是因为ObjectInputStream在继续操作之前先读取OOS发送的标头。

  • 我试图使用web控制台获取页面上所有h2标记中的文本。 我所发现的就是使用每一种,我已经试过了 但是它返回

  • 问题内容: 我想将特定类的每个方法包装在python中,并且希望通过最少地编辑该类的代码来实现。我应该怎么做? 问题答案: Michael Foord的Voidspace博客的一个条目中介绍了一种优雅的实现方法,该条目在“方法修饰元类的方法”部分中介绍了什么是元类以及如何使用它们。稍微简化一下,然后将其应用于您的情况会导致以下结果: 在Python中,函数/方法装饰器只是函数包装器和一些语法糖,以