【问题标题】:Static variables behavior in class level locking类级锁定中的静态变量行为
【发布时间】:2021-11-01 18:52:33
【问题描述】:

我需要对类级锁定中的静态变量行为有所了解。

场景: 考虑下面称为 Data 的类。

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

这里,

  • Thread-A 调用 updateI() 方法并获取锁。
  • 同时Thread-B 正在调用getJ() 方法。
  • 会不会是block Thread-B 因为 Thread-A 已经获取了类级别的锁? 或者它会允许 同时访问这两种方法?

谢谢....

【问题讨论】:

标签: java multithreading


【解决方案1】:

简而言之 - 它不会被锁定。

如果你希望它被锁定,你还需要保护 getJ 函数:

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

这与存在静态变量的事实无关。变量本身不能被锁定。只能访问它们。如果您允许通过 getJ 进行非锁定访问,则没有什么可以阻止您。

【讨论】:

  • 感谢您的快速回答。能详细点吗?
  • @ayan91 - 如果这回答了您的问题,请接受。
【解决方案2】:

有趣的是,即使其他线程正在运行类级别同步方法,您也可以访问类级别变量上的锁

ma​​in 线程和另一个线程 'thread' 将同时运行的示例:

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

}

【讨论】:

    猜你喜欢
    • 2015-10-23
    • 1970-01-01
    • 2011-02-03
    • 1970-01-01
    • 1970-01-01
    • 2010-11-06
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    相关资源
    最近更新 更多