java_线程_生产者消费者模式_信号灯法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40646143/article/details/84696273

需要到Object类中的等待与通知的俩个方法如下

notify()  唤醒正在等待对象监视器的单个线程。 
notifyAll()  唤醒正在等待对象监视器的所有线程。 
wait()  导致当前线程等待,直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。 

其中wait()方法和sleep()方法有明显的不同点 

共同点是:都可以阻塞线程

不同点: wait()方法会释放锁,而sleep()方法则不会释放锁.

1),首先创建一个公用的场景如下

package com.hp.pro;

/**
 * 一个场景一份共同的资源
 *
 * 生产者消费者模式 信号灯法
 */
public class Film {

private String content;
    /**如果 flag 为true 生产者生产  消费者等待  生产完之后通知消费
     *如果  flag 为false 消费者消费  生产者等待  消费完之后通知生产
     */
    private boolean flag=true;

    /**
     * 生产
     */
    public synchronized void play(String content) throws InterruptedException {
        if (!flag){ //生产者等待
            this.wait();
        }
        //开始生产
        Thread.sleep(500);
        this.content=content;
        System.out.println("生产了:" + content);
        //通知消费
        this.notifyAll();
        //生产者停下来
        this.flag=false;
    }

    /**
     * 消费
     */
    public synchronized void watch() throws InterruptedException {
        if (flag){ //消费者等待
            this.wait();
        }
        //开始消费
        Thread.sleep(200);
        System.out.println("消费了"+content);
        //通知生产
        this.notifyAll();
        //让消费者停止
        this.flag=true;
    }
}

2),创建生产者

package com.hp.pro;

/**
 * 生产者
 */
public class Producer implements Runnable {
private Film film;

public Producer(Film film){
    this.film=film;
}
    @Override
    public void run() {
        for (int i = 1; i <= 20; i++) {
            if (i%2==0){
                try {
                    film.play("左青龙");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else{
                try {
                    film.play("右白虎");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

3),创建消费者

package com.hp.pro;

/**
 * 消费者
 */
public class Consumer implements Runnable {
    private Film film;

    public Consumer(Film film){
        this.film=film;
    }

    @Override
    public void run() {
        for (int i = 1; i <= 20; i++) {
            try {
                film.watch();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

4),创建运行的类

package com.hp.pro;

public class APP {
    public static void main (String[] args) {
        Film film1 = new Film();
        Producer film = new Producer(film1);
        Consumer consumer = new Consumer(film1);

        Thread thread1 = new Thread(film);
        Thread thread2 = new Thread(consumer);


        //开启线程
        thread1.start();
        thread2.start();
    }
}

运行效果如下

总结: notify() /notifyAll() /wait()一定要与Synchronized 同步使用否则就同步不了

猜你喜欢

转载自blog.csdn.net/qq_40646143/article/details/84696273