ats*_*rti 12 java multithreading synchronized-block
这项练习直接来自Kathy Seirra和Bert Bates的SCJP
同步代码块
在本练习中,我们将尝试同步一段代码.在该代码块中,我们将获得对象的锁定,以便其他线程在代码块执行时无法修改它.我们将创建三个线程,它们都将尝试操作同一个对象.每个线程将输出一个单个字母100次,然后将该字母递增1.我们将使用的对象是StringBuffer.
我们可以在String对象上进行同步,但是一旦创建了字符串就无法修改它们,因此我们无法在不生成新String对象的情况下增加字母.最终输出应该有100个As,100个B和100个C,所有这些都是不间断的.
我为上面的练习编写了下面的课程(而不是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)
您正在获取正在调用MySyncBlockTest
该run()
方法的实例的锁定.那...不会做任何事情.对该资源没有争议; 每个Thread
都有自己的实例MySyncBlockTest
.