【发布时间】:2013-08-04 11:31:08
【问题描述】:
这个练习直接来自 Kathy Seirra 和 Bert Bates 的 SCJP
同步代码块
在本练习中,我们将尝试同步一段代码。在该代码块中,我们将获得一个对象的锁,以便其他线程在代码块执行时无法修改它。我们将创建三个线程,它们都将尝试操作同一个对象。每个线程将输出一个字母 100 次,然后将该字母加一。我们将使用的对象是 StringBuffer。
我们可以在 String 对象上进行同步,但字符串不能修改一次 它们是被创建的,所以如果不生成新的 String 对象,我们将无法增加字母。最终的输出应该有 100 个 As、100 个 Bs 和 100 个 Cs,全部用不间断的行。
- 创建一个类并扩展 Thread 类。
- 重写 Thread 的 run() 方法。这是同步的地方 代码块会消失。
- 为了让我们的三个线程对象共享同一个对象,我们需要创建 在参数中接受 StringBuffer 对象的构造函数。
- 同步的代码块将获得对 StringBuffer 的锁定 步骤 3 中的对象。
- 在块内,输出StringBuffer 100次,然后递增 StringBuffer 中的字母。您可以查看第 6 章的 StringBuffer 有助于解决此问题的方法。
- 最后,在 main() 方法中,使用 字母 A,然后创建我们类的三个实例并启动所有三个实例。
我为上述练习编写了下面的课程(而不是 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');
}
}
}
我希望得到类似以下的输出(10 个 As、10 个 Bs 和 10 个 Cs),但没有得到。
AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC
相反,我得到了如下不同的输出,因为三个线程是 有机会在另一个完成之前进入循环。
AAAAAAAAAAAAAAAAAA
ABB
ACCCCCCCC
我的问题是为什么run方法中的同步块不起作用?
【问题讨论】:
-
请问,谁降级,发布说明,为什么
-
为什么我得到-1?这是一个真正的问题!
-
可以使用StringBuilder时请不要使用StringBuffer。近 10 年来,StringBuffer 一直是一个遗留类。
-
谢谢彼得,我知道,我只是想跟着练习。
标签: java multithreading synchronized-block