这次演习是直出凯西Seirra和贝尔·贝茨synchronized块不工作
SCJP同步码
块在这个练习中,我们将尝试的代码块同步的。在该代码块中,我们将获取对象的锁定,以便其他线程在代码块执行时无法对其进行修改。我们将创建三个线程,这些线程将尝试操纵同一个对象。每个线程将输出一个字母100次,然后将该字母加1。我们将使用的对象是StringBuffer。
我们可以对一个String对象进行同步,但是一旦创建它们就不能修改它们的字符串 ,所以我们无法在不生成新的String对象的情况下递增字母。最终产出应该有100个As,100 Bs和100 Cs全部在连续的行中。
- 创建一个类并扩展Thread类。
- 重写Thread的run()方法。这是同步的 代码块将去的地方。
- 对于我们的三个线程对象共享相同的对象,我们需要创建一个构造函数,它接受参数中的一个StringBuffer对象。
- 的代码将获得锁的StringBuffer 对象上从步骤3
- 内块,输出StringBuffer的100次,然后递增 在StringBuffer的信同步块。你可以检查第6章的StringBuffer 方法,这将有助于此。
- 最后,在main()方法中,使用字母A创建一个使用 字母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');
}
}
}
我期待的输出类似于下面的(10,10个烧烤和10铯),但没有得到它。
AAAAAAAAAA
BBBBBBBBBB
CCCCCCCCCC
像下面的三个线程相反,我得到了不同的输出 得到一个机会,进入循环其他完成之前。
AAAAAAAAAAAAAAAAAA
ABB
ACCCCCCCC
我的问题是为什么run方法中的synchronized块不工作?
请问,谁降级,发布说明,为什么 –
为什么我会得到-1?它是一个真正的问题! – atsurti
请不要在使用StringBuilder时使用StringBuffer。 StringBuffer已经成为近10年来的传统课程。 –