在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()必须在同步方法/代码块中调用?

使用对象的wait()方法需要注意什么?

Java线程的wait(), notify()和notifyAll()

java中wait方法是啥意思

为什么wait和notify只能在synchronized中?

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