Java 同步方法未按预期工作 [英] Java synchronized method does not work as expected

查看:39
本文介绍了Java 同步方法未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我做了一些研究,但我想我找不到正确的答案.

I did some research but I couldn't find right answer I guess.

public class MultiThreadTwo
{
    private int count = 0;
    public synchronized void increment() // I synchronized it here
    {
        count++;
    }
    public static void main (String [] args)
    {
        MultiThreadTwo app = new MultiThreadTwo();
        app.doWork();
    }
    public void doWork()
    {
        Thread t1 = new Thread(new Runnable() {
            public void run(){
                for (int i=0;i<100;i++ )
                    {
                        increment(); // increments
                    }
            }
        });

        Thread t2 = new Thread(new Runnable() {
            public void run()
            {
                for (int i=0;i<100;i++ )
                    {
                        increment(); // increments
                    }
            }
        });

        t1.start();
        t2.start();

        System.out.println("Count is : "+count);

        try
        {
            t1.join(); // wait for completes
            t2.join(); // wait for completes
        }catch(InterruptedException e)
        {
            e.printStackTrace();
        } 
    }
}

我的输出总是不同的,比如 200,182,171,65,140.我该如何解决这个问题我知道我可以检查 count 的值,如果它不是我预期的值,我可以一次又一次地调用 run 但它根本没有帮助我.synchronized 关键字不应该解决这种情况吗?

My output always diffrent like 200,182,171,65,140. How can I fix this I know I can check the value of count and if it is not the value I expected I can call the run again and again but It doesn't help me at all. synchronized keyword shouldn't fix that situation ?

我错过了什么?

解决方案:加入后打印计数解决了我的问题.

Solution : Printing count after join fixed my problem.

推荐答案

如果您在打印结果之前加入线程并使计数可变,您将始终得到 200.

If you join the threads before priniting the result and make count volatile, you will always get 200.

尽管 volatile 在这里没有害处,但也没有必要.从 t1 和 t2 对 count 的访问工作正常,因为 increment 方法在同一个对象上同步,并且在线程上调用 join 会创建一个发生在之前的关系.因此,即使没有 volatile,主线程也能保证看到正确的计数值.

Eventhough volatile does not harm here, it is not necessary. The accesses to count from t1 and t2 work properly because increment method is synchronized on the same object and calling join on a thread creates a happens-before relationship. Thus, the main thread is guaranteed to see a correct value of count even without volatile, too.

这篇关于Java 同步方法未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆