public class Letters extends Thread
{
private String name;
public Letters(String name)
{
this.name=name;
}
public void write()
{
System.out.println(name);
System.out.println(name);
}
public static void main(String[] args)
{
new Letter("X").start();
new Letter("Y").start();
}
}
如何保证输出为XXYY或YYXX而不是XYXY或其他的形式?
答案中有一个:
public void run()
{
synchronized(Letters.class)
{
write();
}
}
但是我认为锁定的对象是Letters字面量,而这个程序中有两个实例,我总觉得这个答案不正确,高手指点了。
{
private String name;
public Letters(String name)
{
this.name=name;
}
public void write()
{
System.out.println(name);
System.out.println(name);
}
public static void main(String[] args)
{
new Letter("X").start();
new Letter("Y").start();
}
}
如何保证输出为XXYY或YYXX而不是XYXY或其他的形式?
答案中有一个:
public void run()
{
synchronized(Letters.class)
{
write();
}
}
但是我认为锁定的对象是Letters字面量,而这个程序中有两个实例,我总觉得这个答案不正确,高手指点了。
我认为是正确,
new Letter("X").start(); // thread1
new Letter("Y").start(); // thread2thread1 申请锁定 Letter.class 对象
thread2 同样申请 Letter.class 对象因此 thread1 与 thread2 会互斥执行,但无法保证是thread1还是thread2哪个
先获得 Letter.class 对象锁
i.e. 能够保证打印出 XXYY 或 YYXX,但无法确定是打印出XXYY 还是 YYXX
但一定不会出现 XYXY 或 YXYX 等
因为它同步的只是自己的实例变量.
如果这位同学不太明白同步的话你就把这
synchronized(*.class) 这样的同步看做是一个对静态属性的锁定,
因为jvm把每个类加载到jvm内都是一个单一的class对象,
在他建实例时都使用这个class对象来创建实例对象,
也就是说,在一个jvm环境中只能有一个Letter.class对象,
这只锁定了这个对象就每次只能有一个线程可以使用它,
如果下一个线程要进入必须等上一个线程退出后才能进入,
更简单一点,就像一个静态方法一样,
所以
只能有两种情况
1.new Letter("X").start();
当这一行代码运行得快的时候输出:XXYY
2.new Letter("Y").start();
当这行代码运行得快的时候输出:YYXX