Java 线程中调用wait为什么一定要在同步代码块中?

学习线程,在做个练习publicclassBlockedextendsThread{publicBlocked(){start();}publicvoidrun(){tr... 学习线程,在做个练习

public class Blocked extends Thread {
public Blocked() {
start();
}

public void run() {
try {
wait();
} catch (InterruptedException e) {
...
}
}
public static void main(String[] args) {
new Blocked();
}
}

跑起来坏掉了

Exception in thread "Thread-0" java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Object.java:474)
at Blocked.run(Blocked.java:8)

把wait()放到同步代码块中就可以了:
synchronized (this) {
wait();
}

这是为什么呢?
展开
 我来答
samismiling
推荐于2017-09-02 · 知道合伙人软件行家
samismiling
知道合伙人软件行家
采纳数:1340 获赞数:5604

向TA提问 私信TA
展开全部

wait是让使用wait方法的对象等待,暂时先把对象锁给让出来,给其它持有该锁的对象用,其它对象用完后再告知(notify)等待的那个对象可以继续执行了,因此,只有在synchronized块中才有意义(否则,如果大家并不遵循同步机制,那还等谁呢?根本没人排队,也就谈不上等待和唤醒了)
以下是一个例子,用以展示这种机制:

    public class ThreadA {  
        public static void main(String[] args) {  
            ThreadB b = new ThreadB();  
            b.start();//主线程中启动另外一个线程  
            System.out.println("b is start....");  
            //括号里的b是什么意思,应该很好理解吧  
            synchronized(b) {  
                try {  
                    System.out.println("Waiting for b to complete...");  
                    b.wait();//这一句是什么意思,究竟谁等待?  
                    System.out.println("ThreadB is Completed. Now back to main thread");  
                    }catch (InterruptedException e){}  
            }  
            System.out.println("Total is :" + b.total);  
            }  
    }  
      
    class ThreadB extends Thread {  
            int total;  
            public void run() {  
                synchronized(this) {  
                    System.out.println("ThreadB is running..");  
                    for (int i=0; i<=100; i++ ) {  
                        total += i;  
                    }  
                    System.out.println("total is " + total);  
                    notify();  
                }  
            }  
    }


运行结果:
b is start....
Waiting for b to complete...
ThreadB is running..
total is 5050
ThreadB is Completed. Now back to main thread
Total is :5050

lydawen
推荐于2017-10-07 · TA获得超过3181个赞
知道大有可为答主
回答量:2678
采纳率:50%
帮助的人:1542万
展开全部
楼上的回答不负责任,API中这样描述:
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。

对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用:

synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
此方法只应由作为此对象监视器的所有者的线程来调用

注意最后一句: 此方法只应由作为此对象监视器的所有者的线程来调用。如果不给当前对象加锁,你无法拥有当前对象。
本回答被提问者采纳
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
歪瑞顾K
2010-04-02 · TA获得超过2906个赞
知道大有可为答主
回答量:2731
采纳率:33%
帮助的人:2257万
展开全部
因为这个wait就是专门为同步设计的。。。。。。。。。

专门为它设计的,不在它里边用在哪哈儿用呢??
已赞过 已踩过<
你对这个回答的评价是?
评论 收起
收起 1条折叠回答
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式