首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用synchronize获取意外的值

使用synchronize获取意外的值
EN

Stack Overflow用户
提问于 2012-10-28 20:34:07
回答 3查看 98关注 0票数 3

我有一个简单的代码片段,并尝试尝试一下,但在接下来的代码中,我不清楚输出数据的顺序:

代码语言:javascript
复制
public class Main {

    static int n = 100;

    public static synchronized int decreaseValue(){
        return --n;
    }

    public static void main(String[] args) throws InterruptedException, IOException {


        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    try {
                        System.out.println("Thread1: "+ decreaseValue());
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"Thread1");
        t1.start(); 

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){
                    try {
                        System.out.println("Thread2: "+ decreaseValue());
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        },"Thread2");
        t2.start();


        while(true){
            try {
                System.out.println("Main Thread: "+ decreaseValue());
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

我不明白,为什么我会按下一个顺序得到这样的值:

Thread1: 89 Thread2: 90主线程: 88

请注意N值,而不是调用线程的顺序:

代码语言:javascript
复制
Thread1: 99
Thread2: 98
Main Thread: 97
Main Thread: 95
Thread2: 94
Thread1: 96
Main Thread: 92
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-10-28 20:47:41

您一定在某处读到过必须使用synchronized来确保正确的排序,或者类似的东西。“排序”这个词与您脑海中的概念不同:它意味着同步块的执行总是有一些明确的顺序。排序是事先不知道的,但每次都会知道。如果没有同步,您甚至得不到这种保证:一个线程可以感知一个顺序,另一个线程可以感知不同的顺序,或者根本不感知其他线程的任何操作。

关于您的编辑:

如果您担心打印输出顺序混乱,这是因为您的println语句在synchronized之外,因此可以独立于对decreaseValue的调用进行交织。

票数 3
EN

Stack Overflow用户

发布于 2012-10-28 20:41:50

线程并行运行。你不能预测他们的执行顺序。您可以设置线程优先级,确定其执行顺序的优先级。

票数 2
EN

Stack Overflow用户

发布于 2012-10-28 20:37:20

这些线程是并发运行的,并且没有任何东西对它们应该调用您的decreaseValue()函数的位置进行排序。您可能希望它们是有序的,因为您正在执行相同数量的睡眠:),但是一旦线程将从睡眠中启动/恢复,CPU就会将线程放入运行队列(创建执行顺序,这是同步将保证的顺序),因此打印的顺序取决于CPU将线程放入运行队列的方式。

如果您对打印顺序有疑问,控制台上的打印也是同步的(但与decreaseValue不在同一块中)。同样的逻辑也适用于打印,就像减少值一样。

如果希望以值递减的相同顺序查看打印结果,可以在decreaseValue()函数中移动打印。但这不会影响值递减的顺序。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13108824

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档