public class PingPong implements Runnable {
synchronized void hit(long n) {
for (int i = 1; i < 3; i++)
System.out.print(n + "-" + i + " ");
}
public static void main(String[] args) {
new Thread(new PingPong()).start();
new Thread(new PingPong()).start();
}
public void run() {
hit(Thread.currentThread().getId());
}
}
上面的代码给出了输出8-1 9-1 8-2 9-2
但是当功能同步时,它应该输出 8-1 8-2 9-1 9-2或9-1 9-2 8-1 8-2
有人可以解释一下吗?
答案 0 :(得分:7)
'synchronized'同步该方法对特定对象的所有访问。
因此,如果您有1个PingPong
对象,则没有2个线程将同时进入其hit
方法,但是对于2个对象,一个线程可以输入其中一个对象的hit
方法,而另一个线程运行另一个的hit
对象。
这是有道理的,因为您通常使用synchronized
来确保不受干扰地访问当前对象的本地内容。如果您的对象代表线程有时需要不受干扰访问的某个外部实体,请将您的对象设为单个。
答案 1 :(得分:4)
要获得所需的行为,请尝试进行以下更改:
public class PingPong implements Runnable {
synchronized void hit(long n) {
for (int i = 1; i < 3; i++)
System.out.print(n + "-" + i + " ");
}
public static void main(String[] args) {
PingPong p = new PingPong();
new Thread(p).start();
new Thread(p).start();
}
public void run() {
hit(Thread.currentThread().getId());
}
}
只有PingPong
的单个实例,synchronized
上的hit()
修饰符会阻止一个帖子中断另一个,并且您的输出将是X-1 X-2 Y-1 Y-2
或签证-versa。
答案 2 :(得分:1)
根据http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
首先,两次调用同步方法是不可能的 在同一个交错的对象上。
因此,由于您有两个PingPong对象,synchronized关键字无法按预期工作。
答案 3 :(得分:1)
Nope .. synchronized只是意味着一个特定的方法不会同时由两个线程执行,但如果你有两个线程正在工作,他们无论如何都可以以任何顺序调用该方法。简单地说,他们不会同时访问。
此外,它在对象实例上同步。作为两个实例,根本没有同步。
答案 4 :(得分:0)
您没有锁定或解锁标志。所以他们都会在同一时间跑。
T1-&gt;运行() - &GT;命中(); for循环
T2-&gt;运行() - &GT;命中(); for循环
答案 5 :(得分:0)
将您的代码更改为
public class PingPong2 implements Runnable {
private static Object obj = new Object();
void hit(long n) {
synchronized(obj)
{
for (int i = 1; i < 3; i++)
System.out.print(n + "-" + i + " ");
}
}
public static void main(String[] args) {
new Thread(new PingPong2()).start();
new Thread(new PingPong2()).start();
}
public void run() {
hit(Thread.currentThread().getId());
} }