当前位置: 首页 > 知识库问答 >
问题:

如果我不在Java中使用synchronized,程序在哪里知道实例变量的确切值?

令狐俊风
2023-03-14

我正在学习Java多线程,我正在使用同步块和不使用同步块进行一些简单的测试。

public class MultipleMonitorObjects {

    private Object monitor1 = new Object();
    private Object monitor2 = new Object();

    private int counter1 = 0;
//    private int counter2 = 0;

    public void incCounter1() {
//        synchronized (this.monitor1) {
            this.counter1++;
            System.out.println("Inside incCounter1, counter1 = " + counter1);
//        }
    }

    public void incCounter2() {
//        synchronized (this.monitor2) {
            this.counter1++;
            System.out.println("Inside incCounter2, counter1 = " + counter1);
//        }
    }
} 

主类:

public class MultipleMonitorObjectsMain {
    public static void main(String[] args) {
        MultipleMonitorObjects obj = new MultipleMonitorObjects();

        Thread thread1 = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 0; i < 100000; i++) {
                                obj.incCounter1();
                        }
                    }
                }
        );

        Thread thread2 = new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for (int i = 100000; i < 200000; i++) {
                            obj.incCounter2();
                        }
                    }
                }
        );

        thread1.start();
        thread2.start();
    }
}

我不明白的是,为什么如果我评论同步行,计数器正好是 200000。我理解当我使用syncd时的情况,计数器是200000,因为如果有同步块,计数器的值在每次增量后都会添加到主内存中,并且在每次增量之前从主内存中获取,因此程序可以随时知道计数器变量的确切值。但是如果我评论同步行,程序在哪里知道确切的值?我以为最后的值会与 200000 不同。谢谢!

共有1个答案

金泉
2023-03-14

很好,你正在步入多线程的世界。你的程序不应该在最后打印200000。请通过在最后添加这些行来纠正你的程序(在thread2.start()之后)

thread1.join();  //asks main thread to wait until thread1 is finished
thread2.join();  //asks main thread to wait until thread1 is finished
System.out.println(obj.counter1);

现在运行此程序 3 或 4 次,您将看到您的程序每次都会打印不同的值。

此外,如果incCounter1incCounter2方法正在更新相同的 ,那么它们应该在同一个Object上同步(比如 )。如果 incCounter1正在更新 counter1并且 正在更新 counter2,那么您同步 0.05 Object2的方法是正确的。

 类似资料:
  • 问题内容: 我收到此错误: 无法运行程序“ /usr/lib/jvm/java-1.7.0-openjdk-i386/bin/java”(在目录“ /home/sergiy/.AndroidStudioPreview/system/compile-server”中):error = 2,否这样的文件或目录 我删除所有JDK(打开和其他)后,就会发生这种情况。在我从官方站点安装Oracle JDK之

  • 我在anathor php中包含了连接资源文件。我正在做一个小网站。但是当我使用$run_cats=mysqli_query($con,$get_cats);错误来了,mysqli_query希望参数1是mysqli,空给定 我试图把全局$con放在使用的地方,并接近con=mysqli_connect但没有一个工作 这是includes/db。php 在插入产品页面中,包括顶部 这里$con为空

  • 问题内容: 我正在开发jsf应用程序,并使用hibernate模式作为后端。我想创建会话工厂,并在整个应用程序中关闭它。我正在使用util类创建Session工厂。 在我的DAO类的每种方法中,我都会打开会话工厂并关闭它。因此,在我只能打开/关闭会话工厂一次的应用程序中。提前致谢。 问题答案: 在我的应用程序中在哪里打开和在哪里关闭SessionFactory 您正在使用单例会话工厂对象。因此,您

  • 问题内容: 我试图理解Java中捕获变量的概念。 我发现了有关它的详细文章:http : //www.devcodenote.com/2015/04/variable-capture-in- java.html 我不确定字节码部分: 类似地,为了访问封闭方法的局部变量,将创建变量的隐藏副本,并将其保留在内部类 文件 中,该 文件 从该变量访问该变量。 当最终原始值在编译时未知时,如何将其保存到类文

  • 我的程序如何知道要使用什么字符串和数组?这是我对comp sci的介绍中的代码。我们只关注Java。我让用户输入一个句子,然后通过我创建的方法运行该句子,从句子中删除某些字符,然后返回它。 用户使用扫描器kbd填充字符串句子,然后从扫描器中填充ch1、ch2、ch3。 当我写方法的时候 它如何知道,以及进入

  • 本文向大家介绍Java多线程程序中synchronized修饰方法的使用实例,包括了Java多线程程序中synchronized修饰方法的使用实例的使用技巧和注意事项,需要的朋友参考一下 在Java 5以前,是用synchronized关键字来实现锁的功能。 synchronized关键字可以作为方法的修饰符(同步方法),也可作用于函数内的语句(同步代码块)。 掌握synchronized,关键是