【问题标题】:Synchronization by this doesn't prevent concurrency [duplicate]通过此同步不会阻止并发[重复]
【发布时间】:2018-05-26 11:26:28
【问题描述】:

我在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);
    }
}

在我看来,输出应该为零,但绝不是零。调试器显示,随着 run() 方法的运行,THIS 总是会有所不同。为什么会这样?

谢谢。

【问题讨论】:

  • “这个”不正确。这是两个不同的对象,所以不同的同步监视器。一定要使用相同的对象,例如‘final Object lock= new Object();’
  • 您必须锁定同一个对象。 this 对于每个对象都不同。
  • 您很可能想让value 成为原始long 而不是对Long 的引用
  • 请使用“Lesson6.class”而不是“this”

标签: java concurrency synchronization


【解决方案1】:

调试器显示,随着 run() 方法的运行,THIS 总是不同的

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

如果你使用一个通用对象,程序应该可以工作。

顺便说一句,我建议使用原始 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);
    }
}

打印

0

【讨论】:

  • 如此简单...非常感谢!
猜你喜欢
  • 2019-03-07
  • 1970-01-01
  • 2016-01-12
  • 1970-01-01
  • 2012-06-29
  • 1970-01-01
  • 2021-04-07
  • 1970-01-01
  • 2012-08-12
相关资源
最近更新 更多