Java 通过此操作进行同步不会';不能阻止并发

Java 通过此操作进行同步不会';不能阻止并发,java,concurrency,synchronization,Java,Concurrency,Synchronization,我是java多线程方面的新手,如果有人能给我简要解释以下内容,我将不胜感激: 这是我的密码: public class Lesson6 { private static volatile Long value = 0L; public static void main(String[] args) throws InterruptedException { Thread inc = new Thread(new Runnable() {

我是java多线程方面的新手,如果有人能给我简要解释以下内容,我将不胜感激:

这是我的密码:

public class Lesson6 {
    private static volatile Long value = 0L;

    public static void main(String[] args) throws InterruptedException {
        Thread inc = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100_000; i++) {
                    synchronized (this){
                        ++value;
                    }
                }
            }
        });
        inc.start();

        Thread dec = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100_000; i++) {
                    synchronized (this){
                        --value;
                    }
                }
            }
        });
        dec.start();

        inc.join();
        dec.join();

        System.out.println(value);
    }
}
公共课第六课{ 专用静态易失性长值=0L; 公共静态void main(字符串[]args)引发InterruptedException{ 线程inc=新线程(新可运行(){ @凌驾 公开募捐{ 对于(int i=0;i<100_000;i++){ 已同步(此){ ++价值观; } } } }); 公司启动(); Thread dec=新线程(new Runnable(){ @凌驾 公开募捐{ 对于(int i=0;i<100_000;i++){ 已同步(此){ --价值观; } } } }); 12月开始(); 公司加入(); dec.join(); 系统输出打印项次(值); } } 对我来说,输出应该是零,但它永远不会是零。调试器显示,随着run()方法的运行,这一点总是不同的。为什么会发生这种情况

塔克斯

调试器显示,当run()方法运行时,这总是不同的

每个
new Runnable
都是不同的对象,因此
在每种情况下都是不同的

如果使用公共对象,程序应该可以工作

顺便说一句,我建议对值使用原语
long
,而不是引用
long

public class Lesson6 {
    private static volatile long value = 0L;

    public static void main(String[] args) throws InterruptedException {
        final Object locked = new Object();
        Thread inc = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100_000; i++) {
                    synchronized (locked){
                        ++value;
                    }
                }
            }
        });
        inc.start();

        Thread dec = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100_000; i++) {
                    synchronized (locked){
                        --value;
                    }
                }
            }
        });
        dec.start();

        inc.join();
        dec.join();

        System.out.println(value);
    }
}
调试器显示,当run()方法运行时,这总是不同的

每个
new Runnable
都是不同的对象,因此
在每种情况下都是不同的

如果使用公共对象,程序应该可以工作

顺便说一句,我建议对值使用原语
long
,而不是引用
long

public class Lesson6 {
    private static volatile long value = 0L;

    public static void main(String[] args) throws InterruptedException {
        final Object locked = new Object();
        Thread inc = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100_000; i++) {
                    synchronized (locked){
                        ++value;
                    }
                }
            }
        });
        inc.start();

        Thread dec = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100_000; i++) {
                    synchronized (locked){
                        --value;
                    }
                }
            }
        });
        dec.start();

        inc.join();
        dec.join();

        System.out.println(value);
    }
}

“这”是不正确的。这是两个不同的对象,所以不同的同步监视器。请使用相同的对象,例如“最终对象锁定=新对象();”你必须锁定同一个对象<代码>此对于每个对象都是不同的。很可能您希望将
设置为基本
而不是对
的引用。请使用“Lesson6.class”而不是“this”。这是不正确的。这是两个不同的对象,所以不同的同步监视器。请使用相同的对象,例如“最终对象锁定=新对象();”你必须锁定同一个对象
对于每个对象都是不同的。很可能您希望将
设置为基本
而不是
的引用。请使用“Lesson6.class”而不是“this”这样简单…非常感谢!很简单…非常感谢!