昨天,路过https://forums.oracle.com/message/10448617的时候,发现了这个问题:
class SyncClass
{
synchronized void synMthd(String s)
{
System.out.println("[ "+s);
try
{
Thread.sleep(3000);
}
catch(Exception e)
{
System.out.println(e);
}
System.out.println(" ]");
}
}
class Test implements Runnable
{
public static void main(String ar[])
{
Test tt = new Test();
Thread t1 = new Thread(tt,"T1");
Thread t2 = new Thread(tt,"T2");
t1.start();
t2.start();
}
public void run()
{
SyncClass syn = new SyncClass();
Thread th = Thread.currentThread();
// synchronized(syn)
// {
syn.synMthd(th.getName());
// }
}
}
输出结果如图:
也就是说 synchronized不起作用了,为什么没有实现同步,让下一个线程处于阻塞状态,下面我想就这个问题谈点自己的观点:
其实
synchronized void synMthd(String s)
{
System.out.println("[ "+s);
try{
Thread.sleep(3000);
}
catch(Exception e)
{
System.out.println(e);
}
System.out.println(" ]");
}
代码块确实被锁住了,但是在Thread的run方法中创建了对象SyncClass syn = new SyncClass();
因为run这个方法或当前对象没有被锁住,也就是说T1和T2两个线程,分别执行run的时候,创建了两个对象,因为SyncClass的Class类没有被锁住,
所以同时创建了两个对象,当线程T2在调用synMthd(String s)的时候输出 [ T2 ,还没有往
下走的时候,另外一个线程也执行到了这里,并且调用了另外一个对象的该代码块同一时间输出了[ T1,这样就造成synchronized不起作用的结果。
如果在run中锁定this,也就是Test的Class类或着修改成:
public void run() {
SyncClass syn = new SyncClass();
Thread th = Thread.currentThread();
synchronized (syn.getClass()) {
syn.synMthd(th.getName());
}
}
的使用都可以阻塞下一个线程实现同步的。