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

时间:2014-11-20 12:43:43

标签: java multithreading static synchronized

如果一个类只有两个同步方法(静态或非静态),则该类被认为是线程安全的。如果其中一个方法是静态的并且一个非静态方法怎么办?它仍然是线程安全的,或者如果多个线程调用方法会发生错误的事情吗?

有一些像static synchronized and non static synchronized methods in threads这样的类似线程描述了方法调用没有相互阻塞。但我很想知道线程安全世界中的坏事(如状态不一致,竞争条件等)是否会发生。

编辑1:
由于静态方法不能调用非静态方法,因此这方面不应存在线程冲突。另一方面,如果非静态方法调用静态方法,则必须获取类锁。哪个仍然是线程安全的。因此,通过只有两个方法(一个静态的无),我没有看到任何线程冲突。是对的吗?换句话说,我可以看到唯一的问题是非静态方法访问某些静态变量。但如果所有访问都是通过方法完成的,那么我就不会发现任何线程安全问题。这些是我的想法。我不确定我是否遗漏了一些东西,因为我对java并发有点新意。

5 个答案:

答案 0 :(得分:1)

在Java中,以下内容:

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

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

等同于以下内容:

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

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

如您所见,静态方法使用this作为监视对象,而非静态方法使用类对象作为监视器。

由于thisMyClass.class是不同的对象,静态和非静态方法可以同时运行。


To" fix"这样,创建一个专用的静态监视器对象,并在静态和非静态方法中使用它:

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

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

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

答案 1 :(得分:1)

  

如果其中一个方法是静态的并且一个非静态方法怎么办?它仍然是线程安全的,或者如果多个线程调用方法会发生错误的事情吗?

可能会发生不好的事情。

静态方法将锁定类监视器。实例方法将锁定实例监视器。由于使用了两个不同的锁定对象,因此两种方法可以同时从不同的线程执行。如果它们共享状态(即实例方法访问静态数据),您将遇到问题。

答案 2 :(得分:0)

  

如果其中一个方法是静态的并且一个非静态方法怎么办?它仍然是线程安全的,或者如果多个线程调用方法会发生错误的事情吗?

同步适用于对象上的监视器(锁定)

在静态方法的情况下,它是Class's class的对象,在实例方法的情况下,它是this或调用对象。

由于两个对象都不同因此,在多线程的情况下,同步静态和非静态方法都不会相互阻塞。这两种方法都会同时执行。

答案 3 :(得分:0)

  

如果其中一个方法是静态的,一个非静态

,该怎么办?

是的..糟糕的事情可能发生。因为如果您使用static方法进行同步,那么您将锁定Class object上不在类instance上的监视器,即您将锁定MyClass.class。 而当您在实例(非静态)方法上进行同步时,您实际上将锁定当前实例,即this。所以,你锁定了两个不同的对象。因此,行为将未定义肯定不正确

PS:在多线程中,根据经验,请记住 - 如果发生不好的事情,它们就会发生

答案 4 :(得分:0)

  

如果......它仍然是线程安全的吗?

没有完整的例子,无法回答这个问题。线程安全问题从来不是关于方法的问题:这是关于数据结构的破坏和活体保证的问题。没有人知道程序是否是线程安全的,而不知道所有不同的线程做什么,它们做了什么数据,以及它们如何相互协调(同步)。