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

同步静态方法

葛承教
2023-03-14

我正在编写的代码需要在几个静态方法之间进行一些同步。我的目标是阻止执行这些方法中的任何一个,如果其中一个执行。例如:

public class Foo{

       static Object lock = new Object();
       static List<SomeObject> listOfObjects = new ArrayList<>() ;


       public static void methodA() {
              synchronized (lock) {
                  //Do some stuff
                    methodB();
              }
       }

       public static List<SomeObject> methodB() {
              synchronized (lock) {
                  //Do some stuff
                   return listOfObjects;
              }
       }

}

现在让我们假设下面的代码是从代码中的某个地方执行的:

Foo.methodA();
Foo.methodB();

我的问题是:

>

  • 它实际上是同步的吗?methodA和methodB不会同时运行吗?

    如果是,methodA调用methodB会不会造成死锁?

  • 共有3个答案

    嵇丰
    2023-03-14

    不。方法 A 和方法 B 将同时运行,因为同步的不是方法,而是内部的代码。代码将正常继续与具有锁定的任何人一起使用。然后另一种方法将完成。

        public class Foo1 {
    
           static Object        lock          = new Object();
           static List<Integer> listOfObjects = new ArrayList<>();
    
           public static void main(String[] args) {
              new Foo1().start();
           }
           public void start() {
              new Thread(() -> methodA()).start();
              // method A has the lock
              sleep(1000); // sleep 1 second
              // but method B is still entered and prints first
              new Thread(() -> methodB()).start();
           }
           public static void methodA() {
              sleep(5000); // sleep 5 seconds
              System.out.println("Entering methodA()");
              synchronized (lock) {
                 // Do some stuff
                 methodB();
              }
           }
    
           public static List<Integer> methodB() {
              System.out.println("Entering methodB()");
              synchronized (lock) {
                 // Do some stuff
                 return listOfObjects;
              }
           }
    
           static void sleep(int milli) {
              try {
                 Thread.sleep(milli);
              }
              catch (InterruptedException ie) {
              }
           }
    
        }
    
    奚飞星
    2023-03-14

    它实际上是同步的吗?方法 A 和方法 B 不会同时运行吗?

    是的,这个同步看起来不错。< br >一个线程可以多次获取同一个锁,从而增加锁计数器。在它释放所有这些锁之后,只有另一个线程才能获得那个锁。在您的代码中,调用< code>methodA()的线程获取< code>lock两次,一次在< code>methodA()中,另一次在< code>methodB()中。然后它释放它们两次(当同步块结束时)。

    如果是,methodA调用methodB会不会造成死锁?

    不,如上所述,它不会造成死锁,除非您在这些方法中执行一些可能需要永远才能完成的操作,在这种情况下,将会出现饥饿。如果您没有执行任何此类操作,那么我认为当您仅使用一个锁时,您不会陷入死

    温亮
    2023-03-14

    答案:

    1. "它实际上是同步的吗?方法A和方法B不会同时运行吗?"-是的,这些方法是同步的。更准确地说,方法中的代码块是同步的。
    2. "如果是这样,方法A调用方法B会创建死锁吗?"-不,同步关键字本质上是可重入的,这意味着如果一个同步方法调用另一个需要相同锁的同步方法,那么当前持有锁的线程可以进入该方法而无需获取锁"-from 1

    您可以通过提供私有关键字和最终关键字来稍微改进代码:

    private static final Object lock = new Object();
    

    另外,不要返回对要保护的< code>List的直接引用。返回< code >只读视图:

    return Collections.unmodifiableList(listOfObjects);
    

    从现在开始,客户端只有只读访问权限,这可以保护您免受许多意外情况的影响。

    1. 同步块中的静态与非静态锁定对象
    2. Java中的对象级锁与类级锁
     类似资料:
    • 我有点困惑。请看看下面的代码。 我确信调用此序列是可能的。 虽然我仍然有一个小小的困惑,但我们可以很容易地看到也调用方法,这是一个静态方法。方法 是调用非同步静态方法的静态同步方法。当 thread-2 获得类级锁时,为什么从 Thread-1 调用 没有被阻止? 我只是在逻辑上感到困惑,如果一个线程获得类级锁定,则该类其他非同步静态方法保持打开状态,以便从其他方法(实例方法)调用。为什么?

    • 本文向大家介绍java synchronized同步静态方法和同步非静态方法的异同,包括了java synchronized同步静态方法和同步非静态方法的异同的使用技巧和注意事项,需要的朋友参考一下 java synchronized 详解 synchronized关键字有两种用法,一种是只用于方法的定义中,另外一种是synchronized块,我们不仅可以使用synchronized来同步一个对

    • 主要内容:1 什么是Java静态同步方法,2 没有静态同步方法的问题,3 静态同步方法的例子1,4 静态同步方法的例子21 什么是Java静态同步方法 如果将任何静态方法设置为synchronized(同步),则锁定的是类而不是对象。 2 没有静态同步方法的问题 假设有两个共享类(例如:Table类)的对象,分别名为object1和object2。在使用同步方法和同步代码块的情况下,t1和t2或t3和t4之间不会存在干扰,因为t1和t2都引用了一个具有单个锁,但是t1和t3或t2和t4之间可能存

    • 问题内容: 这是我在此链接上找到的一段文字。 “避免锁定静态方法 最糟糕的解决方案是将“ synchronized”关键字放在静态方法上,这意味着它将锁定此类的所有实例。” 为什么同步静态方法会锁定该类的所有实例?它不应该锁定课程吗? 问题答案: 这是我的测试代码,表明您是正确的,并且本文有点过分谨慎: 印刷品: 因此与实例的方法无关… 当然,如果整个系统都使用这些方法,那么您可以期望它们对多线程

    • 当两个线程同时使用不同的实例调用静态同步方法时会发生什么?可能吗?对象锁用于非静态同步方法,但静态同步方法使用什么类型的锁?

    • 问题内容: 任何人都可以解释以下语句吗……“静态同步方法和非静态同步方法不会互相阻塞-它们可以同时运行” 问题答案: 锁定对象在静态方法和非静态方法上有所不同。静态方法将Class对象用作锁(锁obj:),而非静态方法将实例对象用作锁,此时方法的调用已绑定到该对象(锁obj:)。