有人能解释一下为什么这些代码不输出相同的结果(两个代码之间的唯一区别在于 run() 方法)吗?
注意:第一个代码似乎没有做任何锁!
第一个代码:
class LetterThread extends Thread
{
private StringBuffer letter;
public static void main(String[] args) {
StringBuffer sbltr = new StringBuffer("A");
LetterThread one = new LetterThread(sbltr);
LetterThread two = new LetterThread(sbltr);
LetterThread three = new LetterThread(sbltr);
one.setName("Thread ONE");
two.setName("Thread TWO");
three.setName("Thread THREE");
one.start();
two.start();
three.start();
}
LetterThread(StringBuffer letter) {
this.letter = letter;
}
public synchronized void run() {
{
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName() + " (" + x
+ ") = " + letter);
}
letter.setCharAt(0, (char) (letter.charAt(0) + 1));
}
}
}
第二个代码:这段代码的工作完全符合预期
class LetterThread extends Thread
{
private StringBuffer letter;
public static void main(String[] args) {
StringBuffer sbltr = new StringBuffer("A");
LetterThread one = new LetterThread(sbltr);
LetterThread two = new LetterThread(sbltr);
LetterThread three = new LetterThread(sbltr);
one.setName("Thread ONE");
two.setName("Thread TWO");
three.setName("Thread THREE");
one.start();
two.start();
three.start();
}
LetterThread(StringBuffer letter) {
this.letter = letter;
}
public void run() {
synchronized (letter) {
for (int x = 0; x < 100; x++) {
System.out.println(Thread.currentThread().getName() + " (" + x
+ ") = " + letter);
}
letter.setCharAt(0, (char) (letter.charAt(0) + 1));
}
}
最佳答案
第一个代码
事情是你有一个线程的 3 个实例,每个线程都运行它自己的 run()
方法的 synchronized
实例。但是总是只有一个线程等待同步到它自己的 run()
方法,所以它会在线程希望它运行时运行。这导致根本没有同步。
第二个代码
您还有一个线程的 3 个实例,但它们共享一个对字母对象的引用。因此,如果您锁定此引用,线程将相互排斥并且代码按预期运行。
附加信息
这篇文章很好地解释了为什么第一个解决方案不起作用:Should you synchronize the run method? Why or why not?
关于java - 为什么这个同步方法没有按预期工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26610791/