java并发之----实现生产者/消费者模式(操作值&一对一交替打印)

一、实现生产者/消费者模式

1、一生产与一消费:操作值

(1)利用synchronized 实现,代码如下:

public class Producer {
	private String lock;
	public Producer(String lock){
		this.lock = lock;
	}
	
	public void setValue(){
		try{
			synchronized (lock) {
				if(!ValueObject.value.equals("")){
					lock.wait();
				}
				String value = System.currentTimeMillis()+"_"+System.nanoTime();
				System.out.println("set的值是:"+ value);
				ValueObject.value = value;
				lock.notify();
			}
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}
public class Consumer {
	private String lock;
	public Consumer(String lock){
		this.lock = lock;
	}
	
	public void getValue(){
		try{
			synchronized (lock) {
				if(ValueObject.value.equals("")){
					lock.wait();
				}
				System.out.println("get的值是:"+ ValueObject.value);
				ValueObject.value = "";
				lock.notify();
			}
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}
public class ValueObject {
	public static String value = "";
}
public class ThreadP extends Thread{
	private Producer producer;
	
	public ThreadP(Producer producer){
		this.producer = producer;
	}
	
	@Override
	public void run(){
		while(true){
			producer.setValue();
		}
	}
}
public class ThreadC extends Thread{
	private Consumer consumer;
	
	public ThreadC(Consumer consumer){
		this.consumer = consumer;
	}
	
	@Override
	public void run(){
		while(true){
			consumer.getValue();
		}
	}
}
public class PAndC {
	public static void main(String[] args) throws InterruptedException{
		String lock = new String("");
		Producer p = new Producer(lock);
		Consumer c = new Consumer(lock);
		ThreadP threadP = new ThreadP(p);
		ThreadC threadC = new ThreadC(c);
		threadP.start();
		Thread.sleep(1000);
		threadC.start();
	}
}

java并发之----实现生产者/消费者模式(操作值&一对一交替打印)_第1张图片
(2) 利用BlockingQueue阻塞队列实现生产者消费者模式,代码如下:

public class ProducerAndConsumer {
	private static BlockingQueue<String> queue = new ArrayBlockingQueue<>(5);
	
	private static class Producer extends Thread{
		@Override
		public void run(){
			try {
				queue.put("product");
				System.out.println("生产,");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
	private static class Consumer extends Thread{
		@Override
		public void run(){
			try {
				String product = queue.take();
				System.out.println("消费。");
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			
		}
		
	}
	
	public static void main(String[] args){
		for(int i=0; i<3; i++){
			Producer p = new Producer();
			p.start();
		}
		for(int i=0; i<5; i++){
			Consumer c = new Consumer();
			c.start();
		}
		for(int i=0; i<2; i++){
			Producer p = new Producer();
			p.start();
		}
	}
}

java并发之----实现生产者/消费者模式(操作值&一对一交替打印)_第2张图片
这里利用ArrayBlockingQueue来实现生产者消费者模式,解释下上图后四行可能会出现先打印 “消费。” 后打印 “生产,” 的情况,这是因为有消费者线程阻塞了,等待代码中第三个for循环的生产者线程执行完queue.put(“生产,”)之后,阻塞的消费者线程被唤醒然后抢先打印“消费。”,所以会出现这种情况。

2、一对一交替打印A、B

利用ReentrantLock 与Condition 实现,代码如下:

public class MyService {
	private ReentrantLock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	private boolean hasValue = false;
	
	public void printA(){
		try{
			lock.lock();
			while(hasValue == true){
				condition.await();
			}
			System.out.println("打印A");
			hasValue = true;
			condition.signal();
		}catch(InterruptedException e){
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
	
	public void printB(){
		try{
			lock.lock();
			while(hasValue == false){
				condition.await();
			}
			System.out.println("打印B");
			hasValue = false;
			condition.signal();
		}catch(InterruptedException e){
			e.printStackTrace();
		}finally{
			lock.unlock();
		}
	}
}
public class ThreadA extends Thread{
	private MyService service;
	
	public ThreadA(MyService service){
		this.service = service;
	}
	
	@Override
	public void run(){
		for(int i=0; i<5; i++){//交替打印5对A、B,将5替换为Integer.MAX_VALUE即可不断打印
			service.printA();
		}
	}
}

public class ThreadB extends Thread{
	private MyService service;
	
	public ThreadB(MyService service){
		this.service = service;
	}
	
	@Override
	public void run(){
		for(int i=0; i<5; i++){
			service.printB();
		}
	}
}
public class ProducersAndConsumers {

	public static void main(String[] args) {
		MyService service = new MyService();
		
		ThreadA A = new ThreadA(service);
		ThreadB B = new ThreadB(service);
		A.start();
		B.start();
	}
}

java并发之----实现生产者/消费者模式(操作值&一对一交替打印)_第3张图片

二、参考

《Java多线程编程核心技术》高洪岩

你可能感兴趣的:(面试备战,java并发)