
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();
}
这是为什么呢? 展开
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();
}
这是为什么呢? 展开
3个回答
展开全部
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
展开全部
楼上的回答不负责任,API中这样描述:
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。
对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
此方法只应由作为此对象监视器的所有者的线程来调用
注意最后一句: 此方法只应由作为此对象监视器的所有者的线程来调用。如果不给当前对象加锁,你无法拥有当前对象。
导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。换句话说,此方法的行为就好像它仅执行 wait(0) 调用一样。
当前的线程必须拥有此对象监视器。该线程发布对此监视器的所有权并等待,直到其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。然后该线程将等到重新获得对监视器的所有权后才能继续执行。
对于某一个参数的版本,实现中断和虚假唤醒是可能的,而且此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
此方法只应由作为此对象监视器的所有者的线程来调用
注意最后一句: 此方法只应由作为此对象监视器的所有者的线程来调用。如果不给当前对象加锁,你无法拥有当前对象。
本回答被提问者采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
因为这个wait就是专门为同步设计的。。。。。。。。。
专门为它设计的,不在它里边用在哪哈儿用呢??
专门为它设计的,不在它里边用在哪哈儿用呢??
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询