在synchronize代码块中调用wait后还会继续执行后续的代码吗
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在synchronize代码块中调用wait后还会继续执行后续的代码吗相关的知识,希望对你有一定的参考价值。
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
参考技术A 这个应该是这样的吧,wait调用的时候只能用指针啊,要不然怎么把status的值传出来呢?如果还不明白,那么wait的作用就是等待某个子进程退出,wait的返回值就是这个子进程的进程号,而status就是这个子进程exit时的status,而因为一个函数只能有一个返回值,而参数只能传入,所以用指针当参数传入函数来得到status值。exit和wait的参数类型不一致只是形式上不一致,最终结果是一样的,就是得到int型的status值。这个应该不难理解,估计你是程序看太累了,没转过弯来,注意多休息就好了。本回答被提问者采纳
为什么wait和notify只能在synchronized中?
前言
wait和notify必须在synchronized块中,否则会抛出IllegalMonitorStateException。
原因
代码示例
class BlockingQueue {
Queue<String> buffer = new LinkedList<String>();
public void give(String data) {
buffer.add(data);
notify();
}
public String take() throws InterruptedException {
while (buffer.isEmpty())
wait();
return buffer.remove();
}
}
代码示例的问题所在
一个消费者调用take,发现buffer.isEmpty。
在消费者调用wait之前,由于cpu的调度,消费者线程被挂起,生产者调用give,然后notify。
然后消费者调用wait (注意,由于错误的条件判断,导致wait调用在notify之后,这是关键)。
如果很不幸的话,生产者产生了一条消息后就不再生产消息了,那么消费者就会一直挂起,无法消费,造成死锁。
关键
总是让give/notify和take/wait为原子操作。wait/notify是线程之间的通信,他们存在竞态,我们必须保证在满足条件的情况下才进行wait。换句话说,如果不加锁的话,那么wait被调用的时候可能wait的条件已经不满足了(如上述)。由于错误的条件下进行了wait,那么就有可能永远不会被notify到,所以我们需要强制wait/notify在synchronized中。
以上是关于在synchronize代码块中调用wait后还会继续执行后续的代码吗的主要内容,如果未能解决你的问题,请参考以下文章
面试官:为什么wait(),notify()必须在同步方法/代码块中调用?
Java线程的wait(), notify()和notifyAll()