Java使用线程并发库模拟弹夹装弹以及发射子弹的过程

同样是从网上看到的一个需求,需求描述都在代码中。

不多说了,直接贴代码了。相信大家都能够看得懂的!

package cn.yw.bore;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 使用多线程模拟多线程装弹及射出的过程(实际上这是一个生产者与消费者的问题)
 * 
 * 要求:
 *  1.开启3个线程装弹,开启2个线程发射子弹
 *  2.弹夹最多只能够装载12颗子弹
 *  3.一次只能够发射一枚子弹,发射子弹的时候不能进行装弹,在装弹的时候不能进行发射。
 *  4.整个过程就是“装载”、“发射”、“装载”、“发射”、“装载”、“发射”
 * @author yw-tony
 *
 */
public class ClipTest {
    
    public static void main(String[] args){
        final BoreManager manager = new BoreManager();
        //开启3个线程装弹
        for(int i=0;i<3;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    while(true){
                        manager.loading();
                    }
                }
            }).start();
        }
        
        //开启两个线程进行发射
        for(int i=0;i<2;i++){
            new Thread(new Runnable(){
                @Override
                public void run() {
                    while(true){
                        manager.send();
                    }
                    
                }
            }).start();
        }
        
    }
    
    /**
     * 模拟装弹以及发射的管理类
     * @author yw-tony
     *
     */
    static class BoreManager{
        int boreCount = 1;
        boolean flag = false;//线程开启标记
        //队列中对多存储12个子弹
        ArrayBlockingQueue<Integer> blocking = new ArrayBlockingQueue<Integer>(12);
//        List<Integer> blocking = new ArrayList<Integer>();
        Lock lock = new ReentrantLock();
        Condition cond1 = lock.newCondition();
        Condition cond2 = lock.newCondition();
        /**
         * 发射
         */
        public void send(){
            lock.lock();
            try{
                if(!flag){
                    cond1.await();
                }
                if(blocking.size() == 0){
                    flag = false;
                    cond2.signal();
                }else{
                    Integer i = blocking.take();
                    System.out.println("发射第:"+i+"个子弹!");
                    blocking.remove(i);//将该元素从队列中移除
                    Thread.sleep(100);//模拟子弹发射的慢过程
                }
                
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
            
        }
        /**
         * 装载
         */
        public void loading(){
            lock.lock();
            try{
                if(flag){
                    cond2.await();
                }
                if(blocking.size()==12){
                    flag = true;
                    cond1.signal();
                }else{
                    blocking.put(boreCount);
                    System.out.println("第:"+boreCount+"个子弹装载完成!");
                    Thread.sleep(100);//模拟装弹慢过程
                    boreCount++;
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                lock.unlock();
            }
            
        }
    }
}
原文地址:https://www.cnblogs.com/tony-yang-flutter/p/3507398.html