Java实现消费者与生产者模式的3种方式

在本文中,将 Dog 对象中的 name 属性作为生产的对象与消费的对象,当 name 不为空时,生产者(Producer)等待,唤醒消费者(Consumer),当 name 为空时,Consumer等待,唤醒Producer

Dog的定义

package com.taotao.springboot.bean;

public class Dog {

    private String name;

    public Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

接下来就使用 Synchronized ReentrantLock LinkedTransferQueue 三种方式实现生产者与消费者模式

1、Synchronized同步锁实现

package com.taotao.springboot;

import com.taotao.springboot.bean.Dog;
import com.taotao.springboot.bean.Person;

import java.util.concurrent.atomic.LongAdder;

public class ProducerComsumerBySycn {

    static class Producer extends Thread{

        private Object lock;

        private Dog dog;

        LongAdder adder = new LongAdder();

        public Producer(Object lock, Dog dog) {
            super();
            this.lock = lock;
            this.dog = dog;
        }

        @Override
        public void run() {
            while (true) {
                //wait notify必须在同步代码块中进行
                synchronized (lock) {
                    try {
                        if (dog.getName() != null) {
                            //已有dog 等待
                            lock.wait();
                        } else {
                            //生产dog
                            adder.increment();
                            dog.setName("dog "+adder.sum());
                            System.out.println("生产 :"+dog.getName());
                            //唤醒消费者
                            lock.notifyAll();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    static class Consumer extends Thread{

        private Object lock;

        private Dog dog;

        public Consumer(Object lock, Dog dog) {
            super();
            this.lock = lock;
            this.dog = dog;
        }

        @Override
        public void run() {
            while (true){
                //wait notify必须在同步代码块中进行
                synchronized (lock) {
                    try {
                        if (dog.getName() != null) {
                            System.out.println("消费 :"+dog.getName());
                            dog.setName(null);
                            //睡眠2s,不让程序跑太快
                            Thread.sleep(2000L);
                            //唤醒生产者
                            lock.notifyAll();
                        } else {
                            //没有person 可以消费 则等待
                            lock.wait();
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    public static void main(String[] args) {

        Dog dog = new Dog(null);
        //锁
        Object lock = new Object();
        //生产者线程
        Thread producer = new Thread(new Producer(lock,dog));
        //消费者线程
        Thread consumer = new Thread(new Consumer(lock,dog));
        producer.start();
        consumer.start();
    }

}

2、ReentrantLock可重入锁实现

package com.taotao.springboot;

import com.taotao.springboot.bean.Dog;

import java.util.concurrent.atomic.LongAdder;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class ProducerConsumerByReen {
    static class Producer extends Thread {

        private ReentrantLock lock;

        private Dog dog;

        LongAdder adder = new LongAdder();

        private Condition consumerCondition;

        private Condition producerCondition;

        public Producer(ReentrantLock lock, Dog dog, Condition consumerCondition, Condition producerCondition) {
            super();
            this.lock = lock;
            this.dog = dog;
            this.consumerCondition = consumerCondition;
            this.producerCondition = producerCondition;
        }

        @Override
        public void run() {
            while (true) {
                try {
                    lock.lock();
                    if (dog.getName() != null) {
                        //已有dog 等待
                        producerCondition.await();
                    } else {
                        //生产dog
                        adder.increment();
                        dog.setName("dog " + adder.sum());
                        System.out.println("生产 :" + dog.getName());
                        //唤醒消费者
                        consumerCondition.signalAll();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    static class Consumer extends Thread {

        private ReentrantLock lock;

        private Dog dog;

        private Condition consumerCondition;

        private Condition producerCondition;

        public Consumer(ReentrantLock lock, Dog dog, Condition consumerCondition, Condition producerCondition) {
            super();
            this.lock = lock;
            this.dog = dog;
            this.consumerCondition = consumerCondition;
            this.producerCondition = producerCondition;
        }

        @Override
        public void run() {
            while (true) {
                //wait notify必须在同步代码块中进行
                try {
                    lock.lock();
                    if (dog.getName() != null) {
                        System.out.println("消费 :" + dog.getName());
                        dog.setName(null);
                        //睡眠2s,不让程序跑太快
                        Thread.sleep(2000L);
                        //唤醒生产者
                        producerCondition.signalAll();
                    } else {
                        //没有person 可以消费 则等待
                        consumerCondition.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    public static void main(String[] args) {
        Dog dog = new Dog(null);
        //锁
        ReentrantLock lock = new ReentrantLock();
        //消费者condition,控制消费者线程
        Condition consumerCondition = lock.newCondition();
        //生产者condition,控制生产者线程
        Condition producerCondition = lock.newCondition();
        //生产者线程
        Thread producer = new Thread(new Producer(lock, dog, consumerCondition, producerCondition));
        //消费者线程
        Thread consumer = new Thread(new Consumer(lock, dog, consumerCondition, producerCondition));
        producer.start();
        consumer.start();
    }
}

3、LinkedTransferQueue队列实现

测试类

package com.ruiyun.test;

import java.util.concurrent.LinkedTransferQueue;

public class TransferQueueTest {
	public static void main(String[] args) {
		LinkedTransferQueue<Dog> dogs = new LinkedTransferQueue<>();
		Product product = new Product(dogs);
		Comsumer comsumer = new Comsumer(dogs);
		Thread comThread = new Thread(comsumer);
		Thread prothread = new Thread(product);
		prothread.start();
		comThread.start();
	}
}

生产者

package com.ruiyun.test;

import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.atomic.LongAdder;

public class Product extends Thread {
	
	private LinkedTransferQueue<Dog> queue;
    
	private LongAdder adder = new LongAdder();
	
	public Product(LinkedTransferQueue<Dog> queue) {
		super();
		this.queue = queue;
	}

	@Override
	public void run() {
		while(true){
			try {
				adder.increment();
				Thread.sleep(1000L);
				Dog dog = new Dog("dog"+adder.sum());
				//关键实现,消费者空闲时候才会调用transfer()方法,不然会一直阻塞
				queue.transfer(dog);
				System.out.println("product:"+dog.getName());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

消费者

package com.ruiyun.test;

import java.util.concurrent.LinkedTransferQueue;

public class Comsumer extends Thread{
	private LinkedTransferQueue<Dog> queue;
	
	public Comsumer(LinkedTransferQueue<Dog> queue) {
		super();
		this.queue = queue;
	}

	@Override
	public void run() {
		while(true){
			try {
				//从队列里移除第一个元素,如果队列为空,则阻塞
				Dog take = queue.take();
				System.out.println("comsumer:"+take.getName());
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

你可能感兴趣的:(java)