有人可以解释两个我为什么这些代码不输出相同的结果(两个代码之间的唯一区别在于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));
}
}
答案 0 :(得分:1)
第一个代码
问题是你有3个线程实例,每个线程运行它自己的方法synchronized
的{{1}}实例。但总是只有一个线程正在与它自己的run()
方法同步,因此只要线程希望它运行它就会运行。这导致完全没有同步。
第二个代码
您还有3个线程实例,但它们共享引用到字母对象。因此,如果您锁定此引用,则线程将相互排除,代码将按预期运行。
其他信息
这篇文章解释了第一个解决方案不起作用的原因:Should you synchronize the run method? Why or why not?
答案 1 :(得分:0)
如果要同步两个线程,则必须由所有线程锁定共享资源。在run方法(或线程类中的任何实例方法)中进行同步,每个线程锁定它自己的方法,导致根本没有同步。