同步块无法正常工作

ats*_*rti 12 java multithreading synchronized-block

这项练习直接来自Kathy Seirra和Bert Bates的SCJP

同步代码块

在本练习中,我们将尝试同步一段代码.在该代码块中,我们将获得对象的锁定,以便其他线程在代码块执行时无法修改它.我们将创建三个线程,它们都将尝试操作同一个对象.每个线程将输出一个单个字母100次,然后将该字母递增1.我们将使用的对象是StringBuffer.

我们可以在String对象上进行同步,但是一旦创建了字符串就无法修改它们,因此我们无法在不生成新String对象的情况下增加字母.最终输出应该有100个As,100个B和100个C,所有这些都是不间断的.

  1. 创建一个类并扩展Thread类.
  2. 覆盖Thread的run()方法.这是同步代码块的用武之地.
  3. 为了让我们的三个线程对象共享同一个对象,我们需要创建一个在参数中接受StringBuffer对象的构造函数.
  4. synchronized代码块将从步骤3获取StringBuffer对象的锁定.
  5. 在块中,输出StringBuffer 100次,然后在StringBuffer中递增字母.您可以在第6章中查看有助于此的StringBuffer方法.
  6. 最后,在main()方法中,使用字母A创建一个StringBuffer对象,然后创建我们类的三个实例并启动它们中的所有三个.

我为上面的练习编写了下面的课程(而不是100我打印10个字符)

class MySyncBlockTest extends Thread {

    StringBuffer sb;

    MySyncBlockTest(StringBuffer sb) {
        this.sb=sb;
    }

    public static void main (String args[]) {
        StringBuffer sb = new StringBuffer("A");
        MySyncBlockTest t1 = new MySyncBlockTest(sb);
        MySyncBlockTest t2 = new MySyncBlockTest(sb);
        MySyncBlockTest t3 = new MySyncBlockTest(sb);
        t1.start();
        t2.start();
        t3.start();
    }

    public void run() {
        synchronized(this) {
            for (int i=0; i<10; i++) {
                System.out.print(sb);
            }
            System.out.println("");
            if (sb.charAt(0)=='A')
                sb.setCharAt(0, 'B');
            else
                sb.setCharAt(0, 'C');
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我期待的输出类似于以下(10 As,10 B和10 C),但没有得到它.

AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC
Run Code Online (Sandbox Code Playgroud)

相反,我得到了不同的输出,如下所示,因为三个线程在另一个完成之前有机会进入循环.

AAAAAAAAAAAAAAAAAA
ABB
ACCCCCCCC
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么run方法中的synchronized块不起作用?

Bri*_*ach 20

4. synchronized代码块将从步骤3获取StringBuffer对象的锁定.

好吧,你不是那样做的,不是吗?

synchronized(this) {
Run Code Online (Sandbox Code Playgroud)

您正在获取正在调用MySyncBlockTestrun()方法的实例的锁定.那...不会做任何事情.对该资源没有争议; 每个Thread都有自己的实例MySyncBlockTest.

  • 知道了!我已将其更改为 synchronized(sb) 并且可以正常工作! (2认同)