简体   繁体   English

Static 变量在 class 级别锁定中的行为

[英]Static variables behavior in class level locking

I need some clarity on static variables behavior in class level locking.我需要了解 class 级别锁定中的 static 变量行为。

Scenario: Consider below class called Data.场景:考虑下面称为数据的 class。

public class Data {

    private static int i = 1;
    private static int j = 1;


    public void updateI() {
        synchronized (Data.class) {
            ++i;
            System.out.println(fmt() + " > " + Thread.currentThread().getName() + (" UPDATED > "+ i));
        }
    }

    public void getJ() {
        System.out.println(fmt() + " > " + Thread.currentThread().getName() + (" READ > "+ j));
    }
}

Here,这里,

  • Thread-A calls updateI() method and acquires the lock. Thread-A 调用 updateI() 方法并获取锁。
  • At the same time Thread-B is calling getJ() method.同时 Thread-B 正在调用 getJ() 方法。
  • Will it be block Thread-B as class level lock is already acquired by Thread-A?线程-A 已经获得了 class 级别的锁,是否会阻塞线程-B? Or it will allow to access both methods simultaneously?还是允许同时访问这两种方法?

Thanks....谢谢....

In short - it won't be locked.简而言之 - 它不会被锁定。

If you want it to be locked you need to protect the getJ function as well:如果您希望它被锁定,您还需要保护 getJ function:

public void getJ() {
    synchronized (Data.class) {
        System.out.println(fmt() + " > " + Thread.currentThread().getName() + (" READ > "+ j));
    }
}

That has nothing to do with the fact there are static variables.这与存在 static 变量的事实无关。 The variables themselves can't be locked.变量本身不能被锁定。 Only access to them.只能访问它们。 If you allow un-locked access through getJ, there is nothing to stop you.如果您通过 getJ 允许未锁定的访问,则没有什么可以阻止您。

Interestingly, You can access lock on the class level variables even when class level synchronized method is running by some other Thread有趣的是,即使其他线程正在运行 class 级别同步方法,您也可以访问 class 级别变量上的锁

Example where both the main thread and another thread ' thread ' will run at the same time:线程和另一个线程“线程”将同时运行的示例:

import java.util.Arrays;

public class ThreadExample extends Thread {

public ThreadExample() {
}

public ThreadExample(String[] arr) {
    this.arrObj = arr;
}

private String[] arrObj = new String[2];
private final static ThreadExample obj = new ThreadExample(new String[]{"Hello", "World"});

private static synchronized void call() throws InterruptedException {
        obj.arrObj[0] += 'C';
        System.out.println("Inside Thread ... " + Arrays.toString(obj.arrObj));
        Thread.sleep(5000);
        System.out.println("Inside Thread ... Done");
}

@Override
public void run() {
    try {
        call();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }

}

public static void main(String[] args) throws InterruptedException {
    ThreadExample thread = new ThreadExample();

    thread.start();
    Thread.sleep(1000);

    synchronized (ThreadExample.obj) {
        obj.arrObj[1] += "K";
        System.out.println("Main Thread ... " + Arrays.toString(obj.arrObj));
        Thread.sleep(5000);
        System.out.println("Main Thread ... Done");
    }
}

} }

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

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