Java中易失性变量和普通变量的显示区别

发布于 2024-11-02 04:40:56 字数 1280 浏览 0 评论 0原文

我正在尝试创建一个示例来显示易失性变量和普通变量之间的区别,例如:

package main;

public class TestVolatile extends Thread {

    public int l = 5;
    public volatile int m = -1;

    public TestVolatile(String str) {
        super(str);
    }

    public void run() {
        int i = 0;
        while ((l > 1) && (l < 10)) {
            if (m >= 0) {
                m++;
            }
            i++;
            l = 5;
            System.out.println("5=" + i + " m=" + m);
        }

    }

    public static void main(String[] args) throws InterruptedException {
        TestVolatile tva = new TestVolatile("ThreadA");

        tva.start();
        sleep(5);
        synchronized (tva) {
            tva.m = 5;
            tva.l = 10;
        }
    }

}

所以 m 是易失性的,l 不是。我认为退出 while 循环取决于 l 的值。
因为 l 的值不是易失性的 - 在 l 被分配 5 后,m 将至少增加 1 次。但我已经运行了编码 10 次并且始终 m==5。
所以我想我错了。如何解决这个问题?谢谢。

感谢您的回答,但并非所有都运行良好。 我设置如下:

volatile int x = 0;
volatile int y = 0;

所以现在变量必须相同!但事实并非如此。

x: 346946234 y: 346946250
x: 346946418 y: 346946422
x: 346946579 y: 346946582
x: 346946742 y: 346946745
x: 346946911 y: 346946912

I am trying to create an example to display the difference between volatile and usual variables like:

package main;

public class TestVolatile extends Thread {

    public int l = 5;
    public volatile int m = -1;

    public TestVolatile(String str) {
        super(str);
    }

    public void run() {
        int i = 0;
        while ((l > 1) && (l < 10)) {
            if (m >= 0) {
                m++;
            }
            i++;
            l = 5;
            System.out.println("5=" + i + " m=" + m);
        }

    }

    public static void main(String[] args) throws InterruptedException {
        TestVolatile tva = new TestVolatile("ThreadA");

        tva.start();
        sleep(5);
        synchronized (tva) {
            tva.m = 5;
            tva.l = 10;
        }
    }

}

So m is volatile, l is not. I suppose that exiting from the while loop depends on the value of l.
Because the value of l is not volatile - m will be incremented at least 1 time after l has been assigned 5. But I have run the code 10 times and always m==5.
So I suppose that I am wrong. How to fix this problem? Thank you.

Thanks for answers, but not all run well.
I set like:

volatile int x = 0;
volatile int y = 0;

So now the variables have to be the same! But that is not the case.

x: 346946234 y: 346946250
x: 346946418 y: 346946422
x: 346946579 y: 346946582
x: 346946742 y: 346946745
x: 346946911 y: 346946912

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

看轻我的陪伴 2024-11-09 04:40:56

您正在同步主线程和测试线程。因此,Java 保证使其他线程执行的任何更改可见。

顺便说一句,不可能构建一个确定性地显示易失性和非易失性之间差异的示例。您所能希望的最好结果就是获得一个能够以相当高的概率显示差异的程序。如果线程在同一核心上交错运行。你根本无法表现出任何差异。

以下程序在我的计算机上显示了易失性变量和非易失性变量之间的区别。

public class ShowVolatile {

    final static int NUM_THREADS = 1;

    int x = 0;
    volatile int y = 0;

    public static void main(String... args) {

        final ShowVolatile sv = new ShowVolatile();

        for (int i=0; i< NUM_THREADS; i++) {
            new Thread(new Runnable() {
                public void run() {
                    while (true) {
                        sv.x += 1;    
                        sv.y += 1;    
                    }
                }
            }).start();
        }


        while (true) {
            System.out.println("x: " + sv.x + " y: " + sv.y);
        }
    }

}

如果增加线程数,您将看到更多的同步丢失。但线程数为 1 就足够了。至少在我的硬件上是四核 i7。

You are synchronizing the main thread and your test thread. Therefore Java guarantees to make any changes visible performed by the other thread.

Btw, it is impossible to construct an example which deterministically shows a difference between volatile and non-volatile. The best you can hope is to get a program which shows the difference with a quite high probability. If the threads run interleaved on the same core. You won't be able to show any difference at all.

The following program shows on my computer the difference between volatile and non-volatile variables.

public class ShowVolatile {

    final static int NUM_THREADS = 1;

    int x = 0;
    volatile int y = 0;

    public static void main(String... args) {

        final ShowVolatile sv = new ShowVolatile();

        for (int i=0; i< NUM_THREADS; i++) {
            new Thread(new Runnable() {
                public void run() {
                    while (true) {
                        sv.x += 1;    
                        sv.y += 1;    
                    }
                }
            }).start();
        }


        while (true) {
            System.out.println("x: " + sv.x + " y: " + sv.y);
        }
    }

}

If you increase the number of threads you will see additional synchronization misses. But a thread count of 1 is enough. At least on my hardware a Quad-Core i7.

绳情 2024-11-09 04:40:56

让多个线程对 易失性变量执行并发非同步 ++ 应该会有所帮助。然而,它永远不会是确定性的。它还可能取决于底层操作系统和 CPU。

Having multiple threads doing concurrent non-synchronized ++ on your volatile variable should help. However it won't ever be deterministic. It might also depend on the underlying OS and CPU.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文