生产者&消费者

2021-10-19 10:03:59 浏览数 (1)

wait&notify

wait方法的作用是使当前正在执行的线程进入等待状态,wait方法是Object类的方法,该方法用来将当前线程放入到“预执行队列”中,并且在wait所在的代码行进行停止执行,直到接到通知或被中断为止。在调用wait方法之前,线程必须获得该对象的对象锁,也就是说只能在同步方法或同步代码块中调用wait方法。在执行wait方法后,当前线程锁会自动释放,当wait方法返回该线程与其他线程重新竞争获取锁。

notify方法也是要在同步方法或者同步代码块中使用,在调用前必须获得对象的对象锁。这个方式是用来通知那些可能等待锁对象的其他线程,如果有多个线程等待,由线程调试器随机选一个wait状态的线程,向其发出通知,并使等待获取该对象的对象锁。

在执行notify方法后,当前线程不会马上释放该对象的对象锁,wait状态的线程也不能马上获取该对象的对象锁,要等到执行notify方法的线程将任务执行完成后,也就是退出synchronized代码块后,当前线程才会释放锁,wait状态的线程才可以获得锁。

一生产者一消费者

代码语言:javascript复制
public class ThreadTest30 {

    public static void main(String[] args) {

        ThreadVo threadVo = new ThreadVo();

        Thread producer = new ThreadProducer(threadVo);
        producer.setName("生产者");
        producer.start();

        Thread consumer = new ThreadConsumer(threadVo);
        consumer.setName("消费者");
        consumer.start();
    }
}

class ThreadProducer extends Thread{

    private ThreadVo threadVo;

    public ThreadProducer(ThreadVo threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) { 
            threadVo.push(Math.random()   "");
        }
    }
}

class ThreadConsumer extends Thread{

    private ThreadVo threadVo;

    public ThreadConsumer(ThreadVo threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            if (list.size() == 1) {
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName()   "添加数据");
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            this.notify();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            if (list.size() == 0) {
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName()   ": 消费数据: "   returnVal);
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            this.notify();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

执行结果:
生产者添加数据
生产者: 还有:1个数据
生产者等待中
消费者: 消费数据: 0.6627895017650591
消费者: 还有:0个数据
消费者等待中
生产者添加数据
生产者: 还有:1个数据
......

一生产者多消费者

代码语言:javascript复制
public class ThreadTest31 {

    public static void main(String[] args) {

        ThreadVo31 threadVo = new ThreadVo31();

        Thread producer = new ThreadProducer31(threadVo);
        producer.setName("生产者");
        producer.start();

        Thread[] consumers = new Thread[5];
        for (int i = 0; i < consumers.length; i  ) {
            consumers[i] = new ThreadConsumer31(threadVo);
            consumers[i].setName("消费者"   (char)('A'   i));
            consumers[i].start();
        }
    }
}

class ThreadProducer31 extends Thread{

    private ThreadVo31 threadVo;

    public ThreadProducer31(ThreadVo31 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.push(Math.random()   "");
        }
    }
}

class ThreadConsumer31 extends Thread{

    private ThreadVo31 threadVo;

    public ThreadConsumer31(ThreadVo31 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo31 {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            if (list.size() == 1) {
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName()   "添加数据");
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            this.notify();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            while (list.size() == 0) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName()   ": 消费数据: "   returnVal);
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            // 唤醒全部生产者
            this.notifyAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

多生产者一消费者

代码语言:javascript复制
public class ThreadTest32 {

    public static void main(String[] args) {

        ThreadVo32 threadVo = new ThreadVo32();

        Thread[] producsers = new Thread[5];
        for (int i = 0; i < producsers.length; i  ) {
            producsers[i] = new ThreadProducer32(threadVo);
            producsers[i].setName("生产者"   (char)('A'   i));
            producsers[i].start();
        }

        Thread consumer = new ThreadConsumer32(threadVo);
        consumer.setName("消费者");
        consumer.start();
    }
}

class ThreadProducer32 extends Thread{

    private ThreadVo32 threadVo;

    public ThreadProducer32(ThreadVo32 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.push(Math.random()   "");
        }
    }
}

class ThreadConsumer32 extends Thread{

    private ThreadVo32 threadVo;

    public ThreadConsumer32(ThreadVo32 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo32 {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            while (list.size() == 1) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName()   "添加数据");
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            this.notifyAll();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            while (list.size() == 0) {
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName()   ": 消费数据: "   returnVal);
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            // 唤醒全部生产者
            this.notifyAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

多生产者多消费者

代码语言:javascript复制
public class ThreadTest33 {

    public static void main(String[] args) {

        ThreadVo33 threadVo = new ThreadVo33();

        Thread[] producsers = new Thread[5];
        Thread[] consumers = new Thread[5];
        for (int i = 0; i < producsers.length; i  ) {
            producsers[i] = new ThreadProducer33(threadVo);
            producsers[i].setName("生产者"   (char)('A'   i));
            producsers[i].start();

            consumers[i] = new ThreadConsumer33(threadVo);
            consumers[i].setName("消费者"   (char)('A'   i));
            consumers[i].start();
        }
    }
}

class ThreadProducer33 extends Thread{

    private ThreadVo33 threadVo;

    public ThreadProducer33(ThreadVo33 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.push(Math.random()   "");
        }
    }
}

class ThreadConsumer33 extends Thread{

    private ThreadVo33 threadVo;

    public ThreadConsumer33(ThreadVo33 threadVo) {
        this.threadVo = threadVo;
    }

    @Override
    public void run() {
        while (true) {
            threadVo.pop();
        }
    }
}

class ThreadVo33 {

    private List<String> list = new ArrayList<>();

    synchronized public void push(String val) {
        try {
            while (list.size() == 1) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            list.add(val);
            System.out.println(Thread.currentThread().getName()   "添加数据");
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            this.notifyAll();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    synchronized public String pop() {
        String returnVal;
        try {
            while (list.size() == 0) {  // 切记不可用if,容易导致虚假唤醒
                System.out.println(Thread.currentThread().getName()   "等待中");
                this.wait();
            }
            returnVal = list.get(0);
            list.remove(0);
            System.out.println(Thread.currentThread().getName()   ": 消费数据: "   returnVal);
            System.out.println(Thread.currentThread().getName()   ": 还有:"   list.size()   "个数据");
            // 唤醒全部生产者
            this.notifyAll();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}

0 人点赞