简体   繁体   English

Java同步和静态同步方法访问静态字段

[英]Java synchronized and static synchronized method accessing static field

What would be the behaviour of the following program where static synchronized method and instance synchronized method is trying to access static field of same class in different threads? 在静态同步方法和实例同步方法试图访问不同线程中相同类的静态字段的以下程序的行为是什么? Will any thread get blocked? 任何线程都会被阻塞吗? Its very confusing. 它非常混乱。

class MyClass
{
        public static int i = 5;

        public synchronized void m1()
        {
                System.out.println(i); //uses static field i of MyClass
            //T1 is executing this method
        }

        public static synchronized void m3()
        {
            //T2 will be able to call this method on same object lock while it is using
            //static field i???
            System.out.println(i);//uses static field i of MyClass
        }
}

Synchronized instance methods are equivalent of 同步实例方法等效于

public void m1() {
    synchronized(this) {
        ...
    }
}

(well, they are not exactly the same, but the answer to your question does not suffer from that difference). (嗯,它们并不完全相同,但是您的问题的答案不会受到这种差异的影响)。

Synchronized static methods are synchronized on the class: 同步的静态方法在类上同步:

public void m2() {
    synchronized(MyClass.class) {
        ...
    }
}

As you can see, two block are synchronized on difference objects: m1 is synchronized on the instance it is called on, and m2 is synchronized on the instance of Class<MyClass> which represents your class in JVM. 如您所见,两个块在差异对象上同步: m1在调用它的实例上同步,而m2Class<MyClass>实例上同步,该实例表示您在JVM中的类。 So those two methods can be called without blocking each other. 因此可以调用这两种方法而不会互相阻塞。

You are always synchronizing on an object. 您始终在对象上进行同步。

Funciton m1 synchronizes on an instance of an object on which it is called. Funciton m1在调用它的对象的实例上同步。

Function m3 synchronizes on the class itself. 函数m3在类本身上同步。

m1 could be written as: m1可以写成:

        public void m1()
        {
            synchronized(this) { 
                System.out.println(i); //uses static field i of MyClass
                //T1 is executing this method
            }
        }

Therefore you are synchronizing on two different objects and these two methods can acces any global variable concurrently. 因此,您正在两个不同的对象上进行同步,并且这两种方法可以同时访问任何全局变量。

The method m1 and m3 can be executed independently. 方法m1和m3可以独立执行。

Because as you already said static synchronized is on the object. 因为正如您已经说过的, static synchronized在对象上。 Therefore the same as synchronize(MyClass.class) . 因此与synchronize(MyClass.class)相同。

synchronized are instance wide usable. synchronized的实例可用。 So it is only blocked for the instances. 因此,仅在实例中阻止它。 It would be the same as using: 它将与使用相同:

MyClass myClass = new MyClass();
synchronize (myClass)
{
.....
}

Your sample code looks good. 您的示例代码看起来不错。

Best way to assure synchronization of static variables according to me is. 确保根据我的静态变量同步的最佳方法是。 As lock object is not accessible outside your Class. 由于锁对象在您的类之外无法访问。 See below. 见下文。

public class MyClass
{
    private static int i = 0;
    private static final Object lockObject = new Object();

    public void m1() {
        synchronized (lockObject ) {
            //Use you static var
        }
    }

    public void m3() {
        synchronized (lockObject ) {
            //Use you static var
        }
    }
} 

Java does not have any synchronization controls that relate to accessing static fields. Java没有任何与访问静态字段有关的同步控件。

If you make your methods empty, the synchronization will be exactly the same. 如果您将方法设为空,则同步将完全相同。

Specifically, as long as any thread is executing any synchronized static method in that type, all other threads that call synchronized static methods will wait for them to finish, so that at most one synchronized static method will be executing at once. 具体来说,只要任何线程正在执行该类型的任何同步静态方法,所有其他调用同步静态方法的线程都将等待它们完成,以便最多可以立即执行一个同步静态方法。

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

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