A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 ZhaoYuBetter 于 2013-5-17 13:12 编辑

如题,如果一个方法 是 sync 的, 里面 有 this.wait(). 当程序执行到 this.wait()时,是不是 this 锁就放弃了?其他线程可以进来了

public class StopThreadDemo2 {
         publicstatic void main(String[] args) {
                   StopThread2st = new StopThread2();
                   Threadt1 = new Thread(st);
                   Threadt2 = new Thread(st);
                   t1.start();
                   t2.start();

                   intnum = 0;
                   while(true) {
                            if(num++ == 60) {
                                     st.changeFlag();
                                     t1.interrupt();                // 强制恢复冻结线程
                                     t2.interrupt();                // 强制恢复冻结线程
                                     break;
                            }
                            System.out.println(Thread.currentThread().getName()+ "..." + num);
                   }
                   System.out.println("over");
         }
}

class StopThread2 implements Runnable {
         privateboolean flag = true;

         @Override
         publicsynchronized void run() {
                   while(flag) {
                            try{
                                     this.wait();         // 等待,这里如果某个线程 wait了。是不是应该放弃了 this 锁了。其他线程可以进来了。有点疑惑
                            }catch (InterruptedException e) {
                                     System.out.println(Thread.currentThread().getName()+"Exception");
                                     flag= false;                   // 操作标记让线程结束
                            }
                            System.out.println(Thread.currentThread().getName()+ "...... run ");
                   }
         }

         publicvoid changeFlag() {
                   flag= false;
         }
}

评分

参与人数 1技术分 +1 收起 理由
袁梦希 + 1 最好写点代码

查看全部评分

6 个回复

正序浏览
OK 谢谢各位!
回复 使用道具 举报
OK 谢谢各位!
回复 使用道具 举报
1.核心区别:sleep用于线程控制,wait用于线程间的通信。
sleep是Thread类的方法,是让线程休息一段时间,然后自动恢复运行,与其他线程无关,与同步无关,也与锁无关(拿锁时不会释放锁)。
wait是Object类的方法,也就是锁的方法,必然在同步中,根据java7.0的解释(The thread releases ownership of this monitor and waits),wait就是让当前线程释放锁并等待。(java 1.6中文版API翻译是错误的,“该线程发布对此监视器的所有权并等待”,release应该翻译成释放)。
public static void sleep(long millis)
                  throws InterruptedException
Causes the currently executing thread to sleep (temporarily cease execution) for the specified number of milliseconds, subject to the precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.
在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。该线程不丢失任何监视器的所属权。
public final void wait()
                throws InterruptedException
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object. In other words, this method behaves exactly as if it simply performs the call wait(0).
The current thread must own this object's monitor. The thread releases ownership of this monitor and waits until another thread notifies threads waiting on this object's monitor to wake up either through a call to the notify method or the notifyAll method. The thread then waits until it can re-obtain ownership of the monitor and resumes execution.
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。

2.唤醒和中断
sleep一觉睡到自然醒,wait就必须其他拿锁的线程调用notify(唤醒一个)或notifyAll(全部唤醒)方法来唤醒。wait的线程被唤醒后,不会立即执行,它要和其他具备执行资格的线程正常的争抢执行权。
由于sleep和wait会使线程处于阻塞或冻结状态,可能等不到所等的事件而无法终止,所以需要从外部调用interrupt()方法中断他们的阻塞状态,此时就会抛InterruptedException异常(API对这个异常的描述为:当线程在活动之前或活动期间处于正在等待、休眠或占用状态且该线程被中断时,抛出该异常。关于如何处理InterruptedException异常,参见资料http://www.ibm.com/developerworks/cn/java/j-jtp05236.html。)
参考资料:java多线程 sleep()和wait()的区别
http://www.cnblogs.com/octobershiner/archive/2011/10/28/2227705.html
回复 使用道具 举报
你的理解是正确的。

下面补充wait() 和 sleep() 的区别:
1,wait() 执行后,释放执行权,也释放锁,与它同步的线程或者其它的线程都可以拿到执行权。
2,sleep() 执行后,释放执行权,但不释放锁,即与它不拥有同一个锁的线程可以拿到执行权,但与它同步的线程不可以拿到执行权。

对比理解,效果更好。
回复 使用道具 举报
线程在调用wait方法前是会释放掉“锁标志”的。要不然就会死锁了。
回复 使用道具 举报
陈雪琪 来自手机 中级黑马 2013-5-16 23:14:57
沙发
我的理解是wait就是放弃了锁的,因为它放弃了执行资格进入了冻结状态啊,所以具有执行资格的线程就开始强执行权了,谁抢到谁就进来。当然老毕说了,确切的说应该是由cpu说了算执行谁的。来自: Android客户端
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马