Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
714 views
in Technique[技术] by (71.8m points)

multithreading - Concurrency in Java: synchronized static methods

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

let's say I have the following class:

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

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)?


EDIT:

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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; 
        }
    }
}

(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(); }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...