首页 文章

如何在Java中运行不同类实例的线程之间同步静态变量?

提问于
浏览
109

我知道在方法为该对象带来同步之前使用 synchronize 关键字 . 也就是说,将同步运行相同对象实例的2个线程 .

但是,由于同步是在对象级别,因此将不会同步运行该对象的不同实例的2个线程 . 如果我们在由该方法调用的Java类中有一个静态变量,我们希望它在该类的实例之间进行同步 . 这两个实例在两个不同的线程中运行 .

我们可以通过以下方式实现同步吗?

public class Test  
{  
   private static int count = 0;  
   private static final Object lock= new Object();    
   public synchronized void foo() 
  {  
      synchronized(lock)
     {  
         count++;  
     }  
  }  
}

是不是因为我们已经定义了一个静态的对象 lock ,并且我们正在使用关键字 synchronized 来锁定该类,所以静态变量 count 现在在类 Test 的实例之间同步?

4 回答

  • 180

    您可以在课程中同步代码 . 那将是最简单的 .

    public class Test  
        {  
           private static int count = 0;  
           private static final Object lock= new Object();    
           public synchronized void foo() 
          {  
              synchronized(Test.class)
             {  
                 count++;  
             }  
          }  
        }
    

    希望你觉得这个答案很有用 .

  • 60

    如果您只是共享一个计数器,请考虑使用AtomicInteger或java.util.concurrent.atomic包中的其他合适的类:

    public class Test {
    
        private final static AtomicInteger count = new AtomicInteger(0); 
    
        public void foo() {  
            count.incrementAndGet();
        }  
    }
    
  • -1

    是的,它是真实的 .

    如果您创建了两个类的实例

    Test t1 = new Test();
    Test t2 = new Test();
    

    然后t1.foo和t2.foo都在同一个静态对象上同步,因此相互阻塞 .

  • 3

    有几种方法可以同步对静态变量的访问 .

    • 使用同步静态方法 . 这会在类对象上同步 .
    public class Test {
        private static int count = 0;
    
        public static synchronized void incrementCount() {
            count++;
        }
    }
    
    • 在类对象上显式同步 .
    public class Test {
        private static int count = 0;
    
        public void incrementCount() {
            synchronized (Test.class) {
                count++;
            }
        }
    }
    
    • 在其他一些静态对象上同步 .
    public class Test {
        private static int count = 0;
        private static final Object countLock = new Object();
    
        public void incrementCount() {
            synchronized (countLock) {
                count++;
            }
        }
    }
    

    方法3在许多情况下是最好的,因为锁定对象不会暴露在您的类之外 .

相关问题