Java中的并发:同步静态方法 [英] Concurrency in Java: synchronized static methods

查看:132
本文介绍了Java中的并发:同步静态方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解如何在Java中对静态方法进行锁定。

I want to understand how locking is done on static methods in Java.

假设我有以下类:

class Foo {
    private static int bar = 0;
    public static synchronized void inc() { bar++; }
    public synchronized int get() { return bar; }

我的理解是当我打电话给 f.get(),该线程获取对象 f 的锁定,当我执行 Foo.inc()线程获取类 Foo 上的锁。

It's my understanding that when I call f.get(), the thread acquires the lock on the object f and when I do Foo.inc() the thread acquires the lock on the class Foo.

我的问题是两个呼叫如何相互同步?
调用静态方法也会获取所有实例化的锁定,或者相反(这似乎更合理)?

My question is how are the two calls synchronized in respect to each other? Is calling a static method also acquires a lock on all instantiations, or the other way around (which seems more reasonable)?

编辑:

我的问题不完全是如何静态同步有效,但静态和非静态方法如何相互同步。
ie,我不希望两个线程同时调用 f.get() Foo.inc(),但这些方法获得了不同的锁。我的问题是这是如何可以预防的并且在上面的代码中被阻止了。

My question isn't exactly how static synchronized works, but how does static and non-static methods are synchronized with each other. i.e., I don't want two threads to simultaneously call both f.get() and Foo.inc(), but these methods acquire different locks. My question is how is this preventable and is it prevented in the above code.

推荐答案

静态和实例 synchronized 方法彼此无关,因此您需要在它们之间应用一些额外的同步,如下所示:

Static and instance synchronized methods are not related to each other, therefore you need to apply some additional synchronization between them, like this:

class Foo {
    private static int bar = 0;
    public static synchronized void inc() { bar++; }
    public synchronized int get() { 
        synchronized (Foo.class) { // Synchronizes with static synchronized methods
            return bar; 
        }
    }
}

(尽管在这种情况下离开在 get() synchronized 没有意义,因为它不会做任何需要在实例上进行同步的事情) 。

(though in this case leaving synchronized on get() doesn't make sense, since it doesn't do anything that requires synchronization on instance).

小心死锁 - 因为这段代码需要多个锁,所以它应该按照一致的顺序执行,即其他同步的静态方法不应该尝试获取实例锁。

Beware of deadlocks - since this code aquires multiple locks, it should do it in consistent order, i.e. other synchronized static methods shouldn't try to acquire instance locks.

另请注意,使用原子字段可以在没有同步的情况下解决此特定任务:

Also note that this particular task can be solved without synchronization at all, using atomic fields:

class Foo {
    private static AtomicInteger bar = new AtomicInteger(0);
    public static void inc() { bar.getAndIncrement(); }
    public int get() { return bar.get(); }
}

这篇关于Java中的并发:同步静态方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆