简体   繁体   English

Java中静态和非静态方法之间共享的资源

[英]Resource shared between static and non-static methods in java

I know that static synchronized method locked on class object and while instance synchronized method locks on current instance of Object ie this . 我知道static synchronized方法锁定在class对象上,而实例synchronized方法锁定在Object的当前实例(即this

Since both of these object are different they have different lock so while one thread is executing static synchronized method , other thread in java doesn't need to wait for that thread to return instead it will acquire separate lock. 由于这两个对象都不相同,因此它们具有不同的锁,因此当一个线程执行static synchronized方法时,java中的其他线程不需要等待该线程返回,而是将获得单独的锁。

Consider following example 考虑以下示例

public class Test {
  static int count = 0;

  public synchronized void f1(){
    count++;
  }

  public static synchronized void f2(){
    count++;
  }
}

here shared count is not accessed in mutual exclusive fashion which may result in passing incorrect count to caller of f1() while another thread is incrementing count using static f2() method. 在这里,共享计数不能以互斥的方式访问,这可能会导致错误count传递给f1()调用者,而另一个线程正在使用static f2()方法递增count

What is solution over this situation? 在这种情况下有什么解决方案? Am i am asking correct question if not please make me correct? 我是在问正确的问题吗? And if it is a true situation then what solution does java pr ovoids? 并且,如果是真实情况,那么Java应当避免什么解决方案?

You can use synchronized block on the non-static method and it should use the same monitor as the static synchronized method: 您可以对非静态方法使用同步块,并且它应使用与静态同步方法相同的监视器:

public void f1() {
   synchronized(Test.class) {
     count++;
   }
}

The rule of thumb is that static synchronized methods should be used to protect only static variables, while non-static synchronized methods should be used to protect only non-static variables. 经验法则是,静态同步方法应仅用于保护静态变量,而非静态同步方法应仅用于保护非静态变量。

Since count is static, modifying it from a block with non-static synchronization is incorrect. 由于count是静态的,因此从具有非静态同步的块中对其进行修改是不正确的。 To code this correctly, and also to avoid code duplication, call f2 from f1 , like this: 要对此进行正确编码并避免重复代码,请从f1调用f2 ,如下所示:

public void f1(){
    ... // Do something ...
    f2();
    ... // Do something else ...
}

public static synchronized void f2(){
    count++;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM