繁体   English   中英

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

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

如果一个类只有两个同步方法(静态或非静态),则该类被视为线程安全的。 如果其中一种方法是静态的而一种是非静态的,该怎么办? 它仍然是线程安全的,还是如果多个线程调用方法会发生不好的事情?

线程中有一些类似的线程,例如静态同步方法和非静态同步方法,它们描述方法调用之间没有相互阻塞。 但是我很想知道线程安全世界中的坏事(例如不一致的状态,竞争条件等)是否会发生。

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

在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是不同的对象,因此静态和非静态方法可以同时运行。


要“修复”此问题,请创建一个专用的静态监视器对象,并在静态和非静态方法中使用它:

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

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

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

如果其中一种方法是静态的而一种是非静态的,该怎么办? 它仍然是线程安全的,还是如果多个线程调用方法会发生不好的事情?

坏事可能发生。

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

如果其中一种方法是静态的而一种是非静态的,该怎么办? 它仍然是线程安全的,还是如果多个线程调用方法会发生不好的事情?

同步与对对象采取的监控器(锁)一起使用。

在使用静态方法的情况下,它是Class类的对象;在使用实例方法的情况下,它是this对象或调用对象。

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

如果其中一种方法是静态的而一种是非静态的,该怎么办

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

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

如果...该线程仍然安全吗?

没有完整的示例就无法回答该问题。 线程安全性问题从来都不是方法问题:它是有关数据结构损坏和活动性保证的问题。 没有人知道一个程序是否是线程安全的,而又不知道所有不同的线程都在做什么,它们执行什么数据以及它们如何相互协调(同步)。

暂无
暂无

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

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