Java实现生产者和消费者的5种方式

转自https://blog.csdn.net/wowwilliam0/article/details/80875673
面试的时候会让手撕,生产者消费者模式,生产者消费者模式,涉及线程同步与通信的问题。
实现方式有
wait/notify|notifyAll
ReetrantLock锁
阻塞队列
信号量Semaphore
管道输入输出流

wait()和notify()方法的实现

package cn.yu.test;
public class Main {
	private static Integer count = 0;
	private static final Integer full = 10;
	private static Object obj = new Object();
	public static void main(String [] args){
		
	}	
	class Producer implements Runnable{
        
		@Override
		public void run() {
			for(int i = 0;i<10;i++) {
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
				synchronized(obj) {
					while(count == full) {
						try {
							obj.wait();
						} catch (InterruptedException e) {
							
							e.printStackTrace();
						}
					}
					count ++;
					obj.notifyAll();
				}
			}
		}
		
	}
	
	class Consumer implements Runnable{
          
		@Override
		public void run() {
			for(int i = 0;i<10;i++) {
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
				synchronized(obj) {
					while(count == 0) {
						try {
							obj.wait();
						} catch (InterruptedException e) {
							
							e.printStackTrace();
						}
					}
				}
				count --;
				obj.notifyAll();
			}
		}
		
	}
	
}

可重入锁ReentrantLock实现

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
 * 生产者和消费者,ReentrantLock的实现
 * 
 * @author ZGJ
 * @date 2017年6月22日
 */
public class Test2 {
    private static Integer count = 0;
    private static final Integer FULL = 10;
    //创建一个锁对象
    private Lock lock = new ReentrantLock();
    //创建两个条件变量,一个为缓冲区非满,一个为缓冲区非空
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
    public static void main(String[] args) {
        Test2 test2 = new Test2();
        new Thread(test2.new Producer()).start();
        new Thread(test2.new Consumer()).start();
        new Thread(test2.new Producer()).start();
        new Thread(test2.new Consumer()).start();
        new Thread(test2.new Producer()).start();
        new Thread(test2.new Consumer()).start();
        new Thread(test2.new Producer()).start();
        new Thread(test2.new Consumer()).start();
    }
    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //获取锁
                lock.lock();
                try {
                    while (count == FULL) {
                        try {
                            notFull.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    count++;
                    System.out.println(Thread.currentThread().getName()
                            + "生产者生产,目前总共有" + count);
                    //唤醒消费者
                    notEmpty.signal();
                } finally {
                    //释放锁
                    lock.unlock();
                }
            }
        }
    }
    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                lock.lock();
                try {
                    while (count == 0) {
                        try {
                            notEmpty.await();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                    count--;
                    System.out.println(Thread.currentThread().getName()
                            + "消费者消费,目前总共有" + count);
                    notFull.signal();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

阻塞队列BlockingQueue的实现

public class Main {
	
	private static Integer count = 0;
	//创建一个阻塞队列
	final BlockingQueue bolckingQueue = new ArrayBlockingQueue<>(10);
	public static void main(String []args) {
		
	}
	class Producer implements Runnable{
     
		@Override
		public void run() {
		  for(int i = 0;i<10;i++) {
			  try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				
				e.printStackTrace();
			}
			  try {
				bolckingQueue.put(1);
				count ++;
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		  }
		}
		
	}
	
	class Consumer implements Runnable{
        
		@Override
		public void run() {
			for(int i = 0;i<10;i++) {
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
				try {
					bolckingQueue.take();
					count --;
				} catch (InterruptedException e) {
					
					e.printStackTrace();
				}
				
			}
		}
		
	}
	
}

信号量Semaphore的实现

import java.util.concurrent.Semaphore;
/**
 * 使用semaphore信号量实现
 * @author ZGJ
 * @date 2017年6月29日
 */
public class Test4 {
    private static Integer count = 0;
    //创建三个信号量
    final Semaphore notFull = new Semaphore(10);
    final Semaphore notEmpty = new Semaphore(0);
    final Semaphore mutex = new Semaphore(1);
    public static void main(String[] args) {
        Test4 test4 = new Test4();
        new Thread(test4.new Producer()).start();
        new Thread(test4.new Consumer()).start();
        new Thread(test4.new Producer()).start();
        new Thread(test4.new Consumer()).start();
        new Thread(test4.new Producer()).start();
        new Thread(test4.new Consumer()).start();
        new Thread(test4.new Producer()).start();
        new Thread(test4.new Consumer()).start();
    }
    class Producer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    notFull.acquire();
                    mutex.acquire();
                    count++;
                    System.out.println(Thread.currentThread().getName()
                            + "生产者生产,目前总共有" + count);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    mutex.release();
                    notEmpty.release();
                }
            }
        }
    }
    class Consumer implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                try {
                    notEmpty.acquire();
                    mutex.acquire();
                    count--;
                    System.out.println(Thread.currentThread().getName()
                            + "消费者消费,目前总共有" + count);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    mutex.release();
                    notFull.release();
                }
            }
        }
    }
}

管道输入输出流PipedInputStream 和PipedOutputStream实现

/**
 * 使用管道实现生产者消费者模型
 * @author ZGJ
 * @date 2017年6月30日
 */
public class Test5 {
    final PipedInputStream pis = new PipedInputStream();
    final PipedOutputStream pos = new PipedOutputStream();
    {
        try {
            pis.connect(pos);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    class Producer implements Runnable {
        @Override
        public void run() {
            try {
                while(true) {
                    Thread.sleep(1000);
                    int num = (int) (Math.random() * 255);
                    System.out.println(Thread.currentThread().getName() + "生产者生产了一个数字,该数字为: " + num);
                    pos.write(num);
                    pos.flush();
                } 
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    pos.close();
                    pis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    class Consumer implements Runnable {
        @Override
        public void run() {
            try {
                while(true) {
                    Thread.sleep(1000);
                    int num = pis.read();
                    System.out.println("消费者消费了一个数字,该数字为:" + num);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    pos.close();
                    pis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) {
        Test5 test5 = new Test5();
        new Thread(test5.new Producer()).start();
        new Thread(test5.new Consumer()).start();
    }
}

你可能感兴趣的:(Java并发编程)