简体   繁体   English

两种同步方法的线程安全性,一种是静态的,一种是非静态的

[英]thread safety with two synchronized methods, one static, one non static

If a class has only two synchronized methods (both either static or non static), the class is considered to be thread safe. 如果一个类只有两个同步方法(静态或非静态),则该类被视为线程安全的。 What if one of the methods is static and one non static? 如果其中一种方法是静态的而一种是非静态的,该怎么办? Is it still thread safe, or bad things can happen if multiple threads call the methods? 它仍然是线程安全的,还是如果多个线程调用方法会发生不好的事情?

There are some similar threads like static synchronized and non static synchronized methods in threads which describe the method calls are not blocking each other. 线程中有一些类似的线程,例如静态同步方法和非静态同步方法,它们描述方法调用之间没有相互阻塞。 But I am curious to know whether bad things in the world of thread safety (like inconsistent state, race condition, etc) can happen or not. 但是我很想知道线程安全世界中的坏事(例如不一致的状态,竞争条件等)是否会发生。

Edit 1: 编辑1:
Since static methods can't call non static methods, there should be no thread conflict from this side. 由于静态方法不能调用非静态方法,因此从这一方面讲,不应有线程冲突。 On the other hand if a non static method calls the static one, it has to acquire the class lock. 另一方面,如果非静态方法调用静态方法,则它必须获取类锁。 Which would be still thread safe. 这仍然是线程安全的。 So by just having two methods (one static one none) I don't see any thread conflict. 因此,只有两种方法(一种静态方法,一种没有方法),我看不到任何线程冲突。 Is that right? 那正确吗? In other words the only case I can see to have an issue is when the non static method accesses some static variables. 换句话说,我唯一看到的问题是非静态方法访问某些静态变量时。 But if all accesses are done through methods then I don't see any issues with thread safety. 但是,如果所有访问都是通过方法完成的,那么我看不到线程安全性的任何问题。 These were my thoughts. 这些是我的想法。 I am not sure whether I am missing something here since I am a little bit new to java concurrency. 我不确定我是否在这里丢失了某些东西,因为我对Java并发性有点新意。

In Java, the following: 在Java中,以下内容:

public class MyClass
{
    public synchronized void nonStaticMethod()
    {
        // code
    }

    public synchronized static void staticMethod()
    {
        // code
    } 
}

is equivalent to the following: 等效于以下内容:

public class MyClass
{
    public void nonStaticMethod()
    {
      synchronized(this)
      {
          // code
      }
    }

    public void static staticMethod()
    {
      synchronized(MyClass.class)
      {
          // code
      }
    } 
}

As you see, static methods use this as monitor object, and non-static methods use class object as monitor. 如您所见,静态方法将this用作监视器对象,非静态方法将类对象用作监视器。

As this and MyClass.class are different objects, static and non-static methods may run concurrently. 由于thisMyClass.class是不同的对象,因此静态和非静态方法可以同时运行。


To "fix" this, create a dedicated static monitor object and use it in both static and non-static methods: 要“修复”此问题,请创建一个专用的静态监视器对象,并在静态和非静态方法中使用它:

public class MyClass
{
    private static Object monitor = new Object(); 

    public void nonStaticMethod()
    {
      synchronized(monitor)
      {
          // code
      }
    }

    public static void staticMethod()
    {
      synchronized(monitor)
      {
          // code
      }
    } 
}

What if one of the methods is static and one non static? 如果其中一种方法是静态的而一种是非静态的,该怎么办? Is it still thread safe, or bad things can happen if multiple threads call the methods? 它仍然是线程安全的,还是如果多个线程调用方法会发生不好的事情?

Bad things can happen. 坏事可能发生。

The static method will lock on the class monitor. 静态方法将锁定在类监视器上。 The instance method will lock on the instance monitor. 实例方法将锁定在实例监视器上。 Since two different lock objects are in use, both methods could execute at the same time from different threads. 由于使用了两个不同的锁对象,因此这两种方法可以从不同的线程同时执行。 If they share state (ie the instance method accesses static data) you will have problems. 如果它们共享状态(即实例方法访问静态数据),则会遇到问题。

What if one of the methods is static and one non static? 如果其中一种方法是静态的而一种是非静态的,该怎么办? Is it still thread safe, or bad things can happen if multiple threads call the methods? 它仍然是线程安全的,还是如果多个线程调用方法会发生不好的事情?

Synchronization works with monitor (locks) that is taken on object. 同步与对对象采取的监控器(锁)一起使用。

In case of static method it's object of Class's class and in case of instance method it's this or calling object. 在使用静态方法的情况下,它是Class类的对象;在使用实例方法的情况下,它是this对象或调用对象。

Since both the objects are different hence both synchronized static and non-static method will not block each other in case of multi-threading. 由于两个对象都不相同,因此在多线程的情况下,同步的静态方法和非静态方法都不会相互阻塞。 Both the methods will execute simultaneously. 两种方法将同时执行。

What if one of the methods is static and one non static 如果其中一种方法是静态的而一种是非静态的,该怎么办

Yes.. Bad things can happen. 是的。坏事可能发生。 Because if you synchronize on a static method, then you will be locking on the monitor of the Class object not on the class instance ie, you will be locking on MyClass.class . 因为如果您在static方法上进行同步,那么您将锁定在Class object的监视器上,而不是在类instance即,您将锁定在MyClass.class Whereas when you are synchronizing on an instance (non-static) method, you will actually be locking on the current instance ie, this . 而当您在实例(非静态)方法上进行同步时,您实际上将锁定当前实例,this So, you are locking on two different objects. 因此,您要锁定两个不同的对象。 So, the behaviour will be undefined and certainly not correct . 因此,行为将是不确定的,并且肯定是不正确的

PS : In multi-threading, as a rule of thumb, please remember - If bad things can happen, they will happen . PS:在多线程中,根据经验,请记住- 如果发生不好的事情,它们也会发生

What if ... Is it still thread safe? 如果...该线程仍然安全吗?

Can't answer that question without a complete example. 没有完整的示例就无法回答该问题。 The question of thread safety is never a question about methods: It's a question about corruption of data structures and about liveness guarantees. 线程安全性问题从来都不是方法问题:它是有关数据结构损坏和活动性保证的问题。 Nobody can say whether a program is thread safe without knowing what all of the different threads do, what data they do it to, and how they coordinate (synchronize) with one another. 没有人知道一个程序是否是线程安全的,而又不知道所有不同的线程都在做什么,它们执行什么数据以及它们如何相互协调(同步)。

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

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