synchronized关键字是否解决可见性问题?

问题描述 投票:0回答:2
class Q2 {
    static long value;

    public static void main(String[] args) throws InterruptedException{
        Runnable r = () -> {
            for (int i = 0; i < 100000000; i++) {
                synchronized (Q2.class) {
                    value++;    
                }
            }
        };

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        
        t1.start();
        t2.start();

        Thread.sleep(100000); //wait enough time

        System.out.println("value = " + value);
    }
}

我知道如果没有 synchronized 关键字,由于并发问题,输出不会是 200000000。

但是,由于没有附加volatile关键字,我认为可见性问题应该出现在每个线程读取的value值中。

我多次尝试该代码,但输出始终是 200000000。

这只是巧合还是运气?

java multithreading
2个回答
3
投票

但是,由于没有附加volatile关键字,我认为可见性问题应该出现在每个线程读取的value值中。

A

synchronized
块负责内存同步和互斥锁定。它在开始时有一个读取内存屏障,在结束时有一个写入内存屏障,这意味着每个线程在递增它时都会看到最新版本的
value
,并且它们将发布更新后的值离开
synchronized
块。两个线程都在
Q2.class
实例上同步,因此一次只有一个线程执行
value++

关于代码的一些一般性评论:

  • 你应该打电话给
    t1.join(); t2.join();
    而不是睡觉。
    join()
    等待线程结束,并确保主线程获得被加入的线程所做的任何更新。这也意味着主线程将在后台线程完成时立即继续,而无需休眠任意时间。
  • 这可能是一个学术练习,但仅供参考,您可以使用一个
    AtomicInteger
    来包装一个
    volatile int
    字段,并允许您在没有
    synchronized
    块的情况下进行增量。

1
投票

在Java中,任何同步动作都保证了可见性。规范写道

同步动作引发动作的同步关系,定义如下:

  • 监视器 m 上的解锁操作与 m 上的所有后续锁定操作同步(其中“后续”是根据同步顺序定义的)。

  • 对易失性变量 v 的写入(§8.3.1.4)与任何线程对 v 的所有后续读取同步(其中“后续”是根据同步顺序定义的)。

  • 启动线程的动作与它启动的线程中的第一个动作同步。

  • 将默认值(零、假或空)写入每个变量与每个线程中的第一个操作同步。

  • 线程 T1 中的最终操作与另一个线程 T2 中检测到 T1 已终止的任何操作同步。

    T2 可以通过调用 T1.isAlive() 或 T1.join() 来实现。

  • 如果线程 T1 中断线程 T2,则 T1 的中断与任何其他线程(包括 T2)确定 T2 已被中断(通过抛出 InterruptedException 或通过调用 Thread.interrupted 或 Thread.isInterrupted)的任何点同步。

继续说(强调我的):

两个动作可以通过happens-before关系来排序。如果一个动作发生在另一个动作之前,那么第一个 是可见的并且在第二个之前排序。 如果我们有两个动作 x 和 y,我们写 hb(x, y) 来表示 x happens-before y。

  • 如果 x 和 y 是同一个线程的动作,并且 x 在程序顺序中出现在 y 之前,则 hb(x, y)。
  • 从对象构造函数的末尾到该对象的终结器(§12.6)的开始有一个发生前的边缘。
  • 如果动作 x synchronizes-with 后续动作 y,那么我们也有 hb(x, y)。
  • 如果 hb(x, y) 和 hb(y, z),则 hb(x, z)。
© www.soinside.com 2019 - 2024. All rights reserved.