进程与线程之wait,notify,notifyAll解析

wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态。
这三个方法最终调用的都是jvm级的native方法。随着jvm运行平台的不同可能有些许差异。
如果对象调用了wait方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态。打个比喻就是
如果对象调用了notify方法就会通知某个正在等待这个对象的控制权的线程可以继续运行。
如果对象调用了notifyAll方法就会通知所有等待这个对象控制权的线程继续运行。


wait和notify区别、理解

void notify() 
Wakes up a single thread that is waiting on this object’s monitor. 
译:唤醒在此对象监视器上等待的单个线程

void notifyAll() 
Wakes up all threads that are waiting on this object’s monitor. 
译:唤醒在此对象监视器上等待的所有线程

void wait( ) 
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll( ) method for this object. 
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法

void wait(long timeout) 
Causes the current thread to wait until either another thread invokes the notify( ) method or the notifyAll( ) method for this object, or a specified amount of time has elapsed. 
译:导致当前的线程等待,直到其他线程调用此对象的notify() 方法或 notifyAll() 方法,或者指定的时间过完。

void wait(long timeout, int nanos) 
Causes the current thread to wait until another thread invokes the notify( ) method or the notifyAll( ) method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed. 
译:导致当前的线程等待,直到其他线程调用此对象的notify( ) 方法或 notifyAll( ) 方法,或者其他线程打断了当前线程,或者指定的时间过完。

上面是官方文档的简介,引用文章源:https://blog.csdn.net/m0_38144897/article/details/79543790
( 死锁指两个或两个以上的线程为了使用某个临界资源而无限制地等待下去。
死锁出现的最基本原因还是逻辑处理不够严谨,所以一般需要修改程序逻辑才能很好的解决死锁问题 )
其中wait方法有三个over load方法:
wait()
wait(long)
wait(long,int)
wait方法通过参数可以指定等待的时长。如果没有指定参数,默认一直等待直到被通知。

下面是在培训机构学习的关于此知识点的例子,个人觉得理解起来非常舒服。

代码如下

package com.demo;
import java.util.ArrayList;
import java.util.List;
class Apple {
    public final String name = " 苹果 " ;
}
// 装苹果的仓库
class Warehouse {
    // 仓库大小
    public static final int SIZE = 10;
    public List<Apple> list = new ArrayList<Apple>( );
    // 增加苹果
    public synchronized void add() {
        if ( this . list .size()<Warehouse. SIZE ) {
            list .add( new Apple());
            System. out .println( " 生产者生产了 1 个现 " + list .size()+ " " );
            notifyAll(); // wait 的不再 wait, 自已继续,即让 wait 的线程来与自己竞争
        } else {
            try {
                //System.out.println(" 仓库满了,生产者等 ...");
                this .wait();
            } catch (InterruptedException e ) {
                e .printStackTrace();
            }
        }
    }
    // 减少苹果
    public synchronized void reduce() {
        if ( this . list .size()>0) {
            list .remove( list .size()-1);
            System. out .println( " 消费者消费了 1 个现 " + list .size()+ " " );
            notifyAll();
        } else {
            try {
                //System.out.println(" 一仓库空了,消费者等 ...");
                this .wait();
            } catch (Exception e ) {
                e .printStackTrace();
            }
        }
    }
}
 
// 生产者
class ProducerThread extends Thread {
    private Warehouse warehouse ;
    public ProducerThread(Warehouse warehouse ) {
        this . warehouse = warehouse ;
    }
    @Override
    public void run() {
        while ( true ) {
            this . warehouse .add();
            try {
                Thread. sleep (400);
            } catch (InterruptedException e1 ) {
                e1 .printStackTrace();
            }
        }
    }
}
// 消费者
class ConsumerThread extends Thread {
    private Warehouse warehouse ;
    public ConsumerThread(Warehouse warehouse ) {
        this . warehouse = warehouse ;
    }
    @Override
    public void run() {
        while ( true ) {
            this . warehouse .reduce();
            try {
                Thread. sleep (500);
            } catch (InterruptedException e1 ) {
                e1 .printStackTrace();
            }
        }
    }
}
 
public class DemoTest {
    public static void main(String[] args ) {
        Warehouse warehouse = new Warehouse();
        ProducerThread pt = new ProducerThread( warehouse );
        ConsumerThread ct = new ConsumerThread( warehouse );
        ProducerThread pt1 = new ProducerThread( warehouse );
        ConsumerThread ct1 = new ConsumerThread( warehouse );
        ProducerThread pt2 = new ProducerThread( warehouse );
        ConsumerThread ct2 = new ConsumerThread( warehouse );
        pt .start();
        pt1 .start();
        pt2 .start();
        ct .start();
        ct1 .start();
        ct2 .start();
    }
}

猜你喜欢

转载自blog.csdn.net/qq_38257168/article/details/80508387