随笔 - 632  文章 - 17  评论 - 54  阅读 - 93万

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();
            }
            
        }
    }
}
复制代码

 

posted on   飘杨......  阅读(1210)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示