当线程尝试同时调用静态和非静态同步方法时会发生什么?

Mallikarjuna Sangisetty

我有一堂课

public class ThreadExample extends Thread{

    static int count = 0;
    public static synchronized  int increment(){
        return count++;
    }
    public synchronized int decrement(){
        return count--;
    }

}

在这里,我有一种静态方法和一种非静态方法。

第一个线程1调用了同步的方法increment()。它在类级别获取锁。在这里,我的问题是,如果另一个线程2正在调用decrement()方法,那么该线程2是否将获得对decrement()的锁定及其工作方式?

克里斯蒂安·胡杰(Christian Hujer)

synchronized关键字有两个可能的用途。它可以用作方法的修饰符,也可以用作语句此外,synchronized修饰符可以与组合使用static,在这种情况下,目标对象将是封闭类,而不是封闭实例

Scope    | modifiers           | corresponding statement
---------+---------------------+------------------------
static   | synchronized static | synchronized (X.class)
instance | synchronized        | synchronized (this)

如果是方法static synchronized,则class在封闭对象上获得锁class,在您的情况下为ThreadExample.class尽管它们被编译为不同的字节码,但是以下两个方法是等效的:

public class Foo {
    // static method with synchronized modifer
    public static synchronized void foo1() {
        // ...
    }
    // equivalent synchronized statement
    public static void foo2() {
        synchronized (Foo.class) {
            // ...
        }
    }
}

如果一个方法是synchronized(非静态的),则在实例本身上获取锁。尽管它们被编译为不同的字节码,但是以下两个方法是等效的:

public class Foo {
    // instance method with synchronized modifier
    public synchronized void foo3() {
        // ...
    }
    // equivalent synchronized statement
    public void foo4() {
        synchronized (this) {
            // ...
        }
    }
}

因此,increment()decrement()synchronized不同的,并且可能存在竞争状况

因此,该变量count没有得到足够的保护以防止并发更新。

++并且--本身不能是原子的,因为递增或递减值需要读-更新-写周期。从技术上讲,它可能是原子的,因为某些CPU通过提供相应的指令来为此提供原子性,这些指令将保持总线/地址本身的获取,直到执行操作为止。但是JVM并不依赖于这些东西。

如果您需要一个原子整数,则可能要看一下java.util.concurrent.atomic.AtomicInteger

如何synchronized在C中

synchronized使用VM环境方法MonitorEnter()MonitorExit()

陷阱

使用synchronized修饰符时,将在或多或少的内容上进行同步public,即对其他对象和类也可见。监控功能java.lang.Object这对于提供基础设施synchronizedpublic,以及本地函数MonitorEnter()/MonitorExit()等待池的方法wait()notify()notifyAll()如果“其他人”也使用“您的对象/您的类”进行同步,则可能导致意外的错误和死锁。

因此,实际上不使用synchronized修饰符而是synchronizedprivate锁定对象使用语句已成为一种模式,如下所示:

public class Foo {
    private final Object lock = new Object();
    public void foo() {
        synchronized (lock) {
            // ...
        }
    }
}

现在,Foo再也不会被其他同步对象干扰或阻止。您可能会认为有一个合理的用例,但是我想如果您有一个用于跨对象/类边界锁定的用例,那么设计中可能会存在一个很大的缺陷-事情不够独立。

如果需要类锁而不是实例锁,只需将变量设为静态即可。

请注意,进行序列化时,您将必须注意锁对象。最简单的方法是实际上不使用Object,但这是:

public class Lock implements Serializable {}

如果要保存序列化存储,则可以声明该锁transient并在反序列化期间重新创建该锁,但请注意transient final,您需要进行反射readResolve()对它们进行反射,但这是另一回事。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

当两个线程同时调用相同的静态方法时会发生什么?

来自分类Dev

从静态方法调用非静态方法

来自分类Dev

在同步方法内部的线程中的同步块会发生什么?

来自分类Dev

在方法中枚举静态变量并将其设置为null时会发生什么

来自分类Dev

当非静态函数声明跟在静态函数声明之后会发生什么?

来自分类Dev

方法名称和块名称相同时会发生什么?

来自分类Dev

未调用的静态c函数会发生什么

来自分类Dev

当线程进入Java中的同步块/方法时会发生什么情况

来自分类Dev

尝试使用Java捕获-发生异常时会发生什么?

来自分类Dev

线程中静态同步和非静态同步方法的行为差异

来自分类Dev

当两个线程尝试修改/访问并发HashMap中的相同密钥时会发生什么?

来自分类Dev

Swift:为什么没有dynamicType的非静态方法不能调用静态变量和常量(静态let)?

来自分类Dev

当两个并发线程尝试从CopyOnWriteArrayList中删除元素时会发生什么?爪哇

来自分类Dev

将标头包含在静态声明中时会发生什么?

来自分类Dev

为什么在调用非静态方法时会调用结构中的静态构造函数?

来自分类Dev

在没有对象参数的情况下调用非静态成员函数会发生错误

来自分类Dev

同步Lambda调用-受到限制时会发生什么?

来自分类Dev

从中调用Overridden方法时会发生什么?

来自分类Dev

同步调用异步函数时被调用者的线程会发生什么

来自分类Dev

静态和非静态多线程

来自分类Dev

同时调用/运行同步方法

来自分类Dev

GCD:当两个线程想要同时在主线程上执行块时会发生什么

来自分类Dev

在方法中枚举静态变量并将其设置为null时会发生什么

来自分类Dev

当两个进程同时调用register()时会发生什么

来自分类Dev

当方法调用自身的return语句时会发生什么?递归。

来自分类Dev

当几个线程试图调用相同的同步方法时会发生什么?

来自分类Dev

Swift:为什么没有dynamicType的非静态方法不能调用静态变量和常量(静态let)?

来自分类Dev

在 Swift 中,当两个线程获取并设置非线程安全属性时会发生什么?

来自分类Dev

在静态方法中调用非静态方法

Related 相关文章

  1. 1

    当两个线程同时调用相同的静态方法时会发生什么?

  2. 2

    从静态方法调用非静态方法

  3. 3

    在同步方法内部的线程中的同步块会发生什么?

  4. 4

    在方法中枚举静态变量并将其设置为null时会发生什么

  5. 5

    当非静态函数声明跟在静态函数声明之后会发生什么?

  6. 6

    方法名称和块名称相同时会发生什么?

  7. 7

    未调用的静态c函数会发生什么

  8. 8

    当线程进入Java中的同步块/方法时会发生什么情况

  9. 9

    尝试使用Java捕获-发生异常时会发生什么?

  10. 10

    线程中静态同步和非静态同步方法的行为差异

  11. 11

    当两个线程尝试修改/访问并发HashMap中的相同密钥时会发生什么?

  12. 12

    Swift:为什么没有dynamicType的非静态方法不能调用静态变量和常量(静态let)?

  13. 13

    当两个并发线程尝试从CopyOnWriteArrayList中删除元素时会发生什么?爪哇

  14. 14

    将标头包含在静态声明中时会发生什么?

  15. 15

    为什么在调用非静态方法时会调用结构中的静态构造函数?

  16. 16

    在没有对象参数的情况下调用非静态成员函数会发生错误

  17. 17

    同步Lambda调用-受到限制时会发生什么?

  18. 18

    从中调用Overridden方法时会发生什么?

  19. 19

    同步调用异步函数时被调用者的线程会发生什么

  20. 20

    静态和非静态多线程

  21. 21

    同时调用/运行同步方法

  22. 22

    GCD:当两个线程想要同时在主线程上执行块时会发生什么

  23. 23

    在方法中枚举静态变量并将其设置为null时会发生什么

  24. 24

    当两个进程同时调用register()时会发生什么

  25. 25

    当方法调用自身的return语句时会发生什么?递归。

  26. 26

    当几个线程试图调用相同的同步方法时会发生什么?

  27. 27

    Swift:为什么没有dynamicType的非静态方法不能调用静态变量和常量(静态let)?

  28. 28

    在 Swift 中,当两个线程获取并设置非线程安全属性时会发生什么?

  29. 29

    在静态方法中调用非静态方法

热门标签

归档