【发布时间】:2018-03-29 06:54:13
【问题描述】:
我有以下代码:
public class ThreadDemo {
public static void main(String[] args) throws InterruptedException {
ThreadImpl thr = new ThreadImpl();
thr.start();
Thread.sleep(1000);
synchronized(thr){
System.out.println( "MAIN "+thr.hashCode());
System.out.println("Main -->got the lock");
thr.wait();
System.out.println("Main -->Done with waiting");
}
}
}
class ThreadImpl extends Thread{
public synchronized void sayHello(){
System.out.println("Ssay hello ");
}
@Override
public void run() {
synchronized(this){
System.out.println( "METHOD "+this.hashCode());
System.out.println("METHOD Got the lock ");
System.out.println("METHOD Going for sleep ");
for(int i =0;i< 100000;i++);
try {
Thread.sleep(2000);
System.out.println("METHOD Woke up ");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("METHOD Done leaving the thread");
}
}
}
在 ThreadDemo 的 main 方法中,我正在创建一个线程对象 ThreadImpl 并启动它。接下来,主线程休眠 1000ms。
线程的 run 方法将在单独的线程中执行。作为其中的一部分,它循环 100000 次并休眠 2000ms。然后它退出该方法。
主线程唤醒并获取“thr”的锁,然后进入等待状态。由于另一个线程已经完成了它的执行,这个等待应该是永远的。但是,我看到以下结果:
方法 1729414014
方法 得到锁
方法 去睡觉
方法醒来
方法 完成离开线程
主 1729414014
主要 --> 获得了锁
Main -->等待完成
main方法在没有人通知的情况下如何继续执行?
【问题讨论】:
-
docs.oracle.com/javase/8/docs/api/java/lang/…。不要子类化线程。不要在线程上同步。不要等待线程。
-
因为你有一个错字
for(int i =0;i< 100000;i++);- 删除分号 -
同步 Runnable 的 run() 方法是完全没有意义的,除非你想共享 Runnable 本身
-
synchronizingonThread有许多奇怪的含义;尤其是Thread在死亡时调用notifyAll- 这是join框架的一部分。除非您真的知道自己在做什么不要在Thread实例上同步。更好的是,忘记synchronized关键字的存在。 -
@ScaryWombat 分号是故意的。我希望它在不做任何事情的情况下旋转 100000 次。这里的问题是谁在唤醒主线程(代码 sn-p 的第 9 行。)
标签: java multithreading synchronized synchronized-block