同步块无法正常工作 [英] Synchronized block not working

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

问题描述

此练习直接来自SCJP,由Kathy Seirra和Bert Bates提供

This exercise is straight out of SCJP by Kathy Seirra and Bert Bates

同步一段代码

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

In this exercise we will attempt to synchronize a block of code. Within that block of code we will get the lock on an object, so that other threads cannot modify it while the block of code is executing. We will be creating three threads that will all attempt to manipulate the same object. Each thread will output a single letter 100 times, and then increment that letter by one. The object we will be using is StringBuffer.

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

We could synchronize on a String object, but strings cannot be modified once they are created, so we would not be able to increment the letter without generating a new String object. The final output should have 100 As, 100 Bs, and 100 Cs all in unbroken lines.


  1. 创建一个类并扩展Thread类。

  2. 覆盖Thread的run()方法。这是同步的
    代码块的位置。

  3. 为了让我们的三个线程对象共享同一个对象,我们需要创建
    a构造函数来接受一个参数中的StringBuffer对象。

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

  5. 内块,输出StringBuffer 100次,然后在StringBuffer中增加
    的字母。你可以查看第6章中的StringBuffer
    方法来帮助解决这个问题。

  6. 最后,在main()方法中,使用
    字母创建一个StringBuffer对象A,然后创建我们班级的三个实例并启动它们全部三个。

  1. Create a class and extend the Thread class.
  2. Override the run() method of Thread. This is where the synchronized block of code will go.
  3. For our three thread objects to share the same object, we will need to create a constructor that accepts a StringBuffer object in the argument.
  4. The synchronized block of code will obtain a lock on the StringBuffer object from step 3.
  5. Within the block, output the StringBuffer 100 times and then increment the letter in the StringBuffer. You can check Chapter 6 for StringBuffer methods that will help with this.
  6. Finally, in the main() method, create a single StringBuffer object using the letter A, then create three instances of our class and start all three of them.

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

I have written the below class for the above exercise (instead of 100 I am printing 10 characters)

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');
        }
    }
}

我期待输出的东西喜欢以下(10 As,10 B和10 C)但没有得到它。

I was expecting an output something like the following (10 As, 10 Bs and 10 Cs) but did not get it.

AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC

相反,由于三个线程为
,我得到的变量如下所示在另一个完成之前有机会进入循环。

Instead I got varying outputs like the following as the three threads are getting a chance to get into the loop before the other has finished.

AAAAAAAAAAAAAAAAAA
ABB
ACCCCCCCC

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

My question is why is the synchronized block in the run method not working?

推荐答案


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

4. The synchronized block of code will obtain a lock on the StringBuffer object from step 3.

嗯,你没有这样做,是你呢?

Well, you're not doing that, are you?

synchronized(this) {

您正在获取 MySyncBlockTest 实例上的锁定,其中 run()方法。那...不会做任何事情。对该资源没有争议;每个线程都有自己的 MySyncBlockTest 的实例。

You're obtaining a lock on the instance of MySyncBlockTest on which that run() method is being called. That ... isn't going to do anything. There's no contention for that resource; each Thread has its own instance of MySyncBlockTest.

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

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