有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用volatile跳过方法执行

我从未经常使用volatile。如果另一个线程执行它,是否可以使用它跳过方法执行? 我认为在下面的代码中,仍然可能有多个线程通过检查并执行该方法。不是吗

private static boolean volatile test = false;
...
    public void test() {
        if (test) {
            return;
        }
        test = true;
        try {
            System.out.println("test() started in Thread with ID " + Thread.currentThread().getId());
            Thread.sleep(10000);
            System.out.println("test() finished in Thread with ID " + Thread.currentThread().getId());
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        test = false;
    }

用例: 该方法可以定期运行,但同时可以由用户手动触发。没有理由使用synchronized关键字一个接一个地运行两次。 求你了,告诉我用volatile是可行的。否则,除了工作面试之外,我看不出任何理由去理解它:) 其他不基于volatile的解决方案是受欢迎的


共 (1) 个答案

  1. # 1 楼答案

    您可以像这样使用volatile AtomicBoolean来实现您的需求

    // default false so that first-thread that test() can enter the logic block
    // AtomicBoolean's value is inherently volatile, so no need to declare volatile here
    private static final AtomicBoolean test = new AtomicBoolean(false);   
    
    
    public void test() {
        if (test.compareAndSet(false, true)) {  // check if the test if previously false and if so update it to true
            try {
                System.out.println("test() started in Thread with ID " + Thread.currentThread().getId());
                Thread.sleep(10000);
                System.out.println("test() finished in Thread with ID " + Thread.currentThread().getId());
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                test.set(false); // executing thread now re-sets the test value
            }
        }
    }