Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java静态字段将在线程之间同步? 公共类ThreadsDemo{ 公共静态int n=0; 专用静态最终整数n读取=300; 公共静态void main(字符串[]argv)引发InterruptedException{ 最终倒计时锁存器cdl=新倒计时锁存器(n次读取); 对于(int i=0;i_Java_Multithreading_Synchronization - Fatal编程技术网

java静态字段将在线程之间同步? 公共类ThreadsDemo{ 公共静态int n=0; 专用静态最终整数n读取=300; 公共静态void main(字符串[]argv)引发InterruptedException{ 最终倒计时锁存器cdl=新倒计时锁存器(n次读取); 对于(int i=0;i

java静态字段将在线程之间同步? 公共类ThreadsDemo{ 公共静态int n=0; 专用静态最终整数n读取=300; 公共静态void main(字符串[]argv)引发InterruptedException{ 最终倒计时锁存器cdl=新倒计时锁存器(n次读取); 对于(int i=0;i,java,multithreading,synchronization,Java,Multithreading,Synchronization,为什么输出为“n为:300”?n不是显式同步的。如果我取消注释“Thread.sleep”,则输出为“n为:299或更少” Java静态字段将在线程之间同步 不可以。根据您的使用模式,您应该将其设置为易变的,或者同步对它的所有访问。您最好使用它 这个问题将帮助您进行描述和示例:静态上下文需要锁定类而不是对象。如果需要同步静态变量,而不需要将其缓存在本地线程中,则需要将其声明为volatile。我以这种方式更改了代码: public class ThreadsDemo { public s

为什么输出为“n为:300”?n不是显式同步的。如果我取消注释“Thread.sleep”,则输出为“n为:299或更少”

Java静态字段将在线程之间同步

不可以。根据您的使用模式,您应该将其设置为易变的,或者同步对它的所有访问。

您最好使用它


这个问题将帮助您进行描述和示例:

静态上下文需要锁定类而不是对象。如果需要同步静态变量,而不需要将其缓存在本地线程中,则需要将其声明为volatile。

我以这种方式更改了代码:

public class ThreadsDemo {
    public static int n = 0;
    private static final int NTHREADS = 300;

    public static void main(String[] argv) throws InterruptedException {
        final CountDownLatch cdl = new CountDownLatch(NTHREADS);
        for (int i = 0; i < NTHREADS; i++) {
            new Thread(new Runnable() {
                public void run() {
//                    try {
//                        Thread.sleep(10);
//                    } catch (InterruptedException e) {
//                        e.printStackTrace();
//                    }
                    n += 1;

                    cdl.countDown();
                }
            }).start();
        }

        cdl.await();
        System.out.println("fxxk, n is: " + n);
    }
}
private static final int NTHREADS=300;
私有静态AtomicInteger n=新的AtomicInteger();
公共静态void main(字符串[]argv)引发InterruptedException{
最终倒计时锁存器cdl=新倒计时锁存器(n次读取);
对于(int i=0;i
你必须应付比赛条件。所有300个线程同时修改
n
。例如:如果两个线程同时读取并递增
n
,则两个线程将
n
递增到相同的值

这就是为什么
n
并不总是
300
,在这种情况下,您会损失一个增量。这种情况可能零次或多次发生

我将
n
int
更改为
AtomicInteger
,这是线程安全的。现在一切正常。

public-class-ThreadsDemo{
private static final int NTHREADS = 300;
private static AtomicInteger n = new AtomicInteger();

public static void main(String[] argv) throws InterruptedException {
    final CountDownLatch cdl = new CountDownLatch(NTHREADS);
    for (int i = 0; i < NTHREADS; i++) {
        new Thread(new Runnable() {
            public void run() {
                n.incrementAndGet();
                cdl.countDown();
            }
        }).start();
    }
    cdl.await();
    System.out.println("fxxk, n is: " + n);
}
公共静态int n=0; 私有静态最终整数n读取=30; 公共静态void main(字符串[]argv)引发InterruptedException{ 最终倒计时锁存器cdl=新倒计时锁存器(n次读取); 对于(int i=0;i
输出“n为:29953”
我认为原因是,线程运行的时间很短,jvm不进行上下文切换。

一种解释是,您的主线程(即产生其他300个线程的线程)在任何其他线程更改运行并增加
n
计数器之前到达了print语句。顺便说一句,您可能应该使
n
线程安全,因为可以有多个线程同时修改它。
synchronized(ThreadsDemo.class){n+=1;}
将使它同步我闭着眼睛穿过街道三次,我没有死于事故。这意味着安全吗?不,这只是意味着你很幸运。你使用了Thread.sleep,它让你能够执行同步操作,你得到了300个答案,但正如JB Nizet所建议的,你是幸运的一个,当你注释Thread.sleep时,没有任何停顿的每个线程都会执行,因此你的主线程和所有其他线程都不同步,它会给你299或更少。使其不稳定不会使n+=1原子。没错。Volatile使用lock#指令前缀和内存屏障。但如果旧x在寄存器中。稍后写入内存将隐藏最后一次写入。是的,我知道AtomicInteger,但我的问题是:当n没有显式同步时,为什么输出是300。@RongbinOu你很幸运。多次运行它,将提供不同的结果。@RongbinOu多线程的一个方面是,当您编写非同步代码时,这将以多种方式进行测试,手动测试团队感到沮丧,因为他们无法再现问题的步骤,并且自动测试可能在本地成功运行,但在CI服务器上中断:)我的问题是:当n未显式同步时,为什么输出为300。因为如果幸运的话,不会发生竞速情况。考虑一个单处理器机器,其中线程从不在读取和递增<代码> N< /代码>之间停顿。纯粹是运气。或者将
300
减少到
2
,您几乎不会观察到与
2
不同的值。将
300
增加到
9999999
,您在多核机器上几乎总能观察到小于
9999999
的值:(我使用了3000个线程,但n是正确的。如果我取消注释这些语句,我确实会看到争用条件。在我真正的4核机器上,当使用
int
而不是
AtomicInteger
时,我观察到的值几乎总是小于
300
。您有多少个真正的核?sysctl-n hw.ncpu 8
public class ThreadsDemo {
    public static int n = 0;
    private static final int NTHREADS = 30;

    public static void main(String[] argv) throws InterruptedException {
        final CountDownLatch cdl = new CountDownLatch(NTHREADS);
        for (int i = 0; i < NTHREADS; i++) {
            new Thread(new Runnable() {
                public void run() {
                    for (int j = 0; j < 1000; j++) // run a long time duration
                        n += 1;
                    cdl.countDown();
                }
            }).start();
        }

        cdl.await();
        System.out.println("fxxk, n is: " + n);
    }
}