为什么这个同步方法没有按预期工作? [英] why this synchronized method is not working as expected?

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

问题描述

有人可以解释两个我为什么这些代码不输出相同的结果(两个代码之间的唯一区别在于run()方法)?

Could someone explain two me why these to codes dont output the same results (the only difference between two codes is in the run() method) ?

NB:第一个代码似乎没有锁定!

NB: the first code seems not doing any lock!

第一个代码:

class LetterThread extends Thread 
{

    private StringBuffer letter;

    public static void main(String[] args) {
        StringBuffer sbltr = new StringBuffer("A");

        LetterThread one = new LetterThread(sbltr);
        LetterThread two = new LetterThread(sbltr);
        LetterThread three = new LetterThread(sbltr);

        one.setName("Thread ONE");
        two.setName("Thread TWO");
        three.setName("Thread THREE");

        one.start();
        two.start();
        three.start();

    }

    LetterThread(StringBuffer letter) {
        this.letter = letter;
    }

    public synchronized void run() {
        {
            for (int x = 0; x < 100; x++) {
                System.out.println(Thread.currentThread().getName() + " (" + x
                        + ") = " + letter);
            }

            letter.setCharAt(0, (char) (letter.charAt(0) + 1));
        }
    }
}

第二代码: 此代码正在按预期工作

Second Code: this code is working exactely as expecting to

class LetterThread extends Thread 
{

    private StringBuffer letter;

    public static void main(String[] args) {
        StringBuffer sbltr = new StringBuffer("A");

        LetterThread one = new LetterThread(sbltr);
        LetterThread two = new LetterThread(sbltr);
        LetterThread three = new LetterThread(sbltr);

        one.setName("Thread ONE");
        two.setName("Thread TWO");
        three.setName("Thread THREE");

        one.start();
        two.start();
        three.start();

    }

    LetterThread(StringBuffer letter) {
        this.letter = letter;
    }

    public void run() {
        synchronized (letter) {
            for (int x = 0; x < 100; x++) {
                System.out.println(Thread.currentThread().getName() + " (" + x
                        + ") = " + letter);
            }

            letter.setCharAt(0, (char) (letter.charAt(0) + 1));
        }
    }


推荐答案

第一个代码

问题是你有3个线程实例,每个线程运行它自己的 synchronized 方法的实例 run()。但总是只有一个线程正在与它自己的 run()方法同步,因此只要线程希望它运行它就会运行。这导致完全没有同步。

The thing is that you have 3 instances of a thread and each threads runs it's own synchronized instance of the method run(). But there is always only one thread that is wating to be synchronized to it's own run() method, so it will run whenever the threads wants it to run. This results in no synchronization at all.

第二个代码

你也有3个线程实例,但它们共享一个引用到字母对象。因此,如果您锁定此引用,则线程将相互排除,代码将按预期运行。

You have also 3 instances of a thread, but they share a reference to the letter object. Therefore if you lock this reference, the threads will exclude each other and the code runs as expected.

其他信息

这篇文章解释了第一个解决方案不起作用的原因:你应该同步run方法吗?为什么或为什么不呢?

This post explains pretty good why the first solution doesn't work: Should you synchronize the run method? Why or why not?

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

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