实战应用:队列+多线程通信+监听

场景:
每1个台设备每次上传文件,只能单个文件上传,假如A设备有10个文件,B设备有10个文件。我要让AB两个设备10文件同时上传,比如A设备正在上传文件1号其他9个文件进入队列等待,B设备也是正在上传文件1号其他9个文件进入队列等待。AB设备共用同一个队列(先进先出队列)只有等A设备第一个文件上传成功了,才能继续上传A的。B也是这样的。

demo1:

public static ConcurrentHashMap<Integer, ConcurrentLinkedQueue<String>> devicesUploadFileMap = new ConcurrentHashMap<>();

    public static ConcurrentHashMap<Integer, Thread> waiters = new ConcurrentHashMap<>();


    public static void main(String[] args) throws InterruptedException {
        // 监听队列 线程.....
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                while (true) { //监听队列中的数据......
                    Thread.sleep(1000L);
                    Set<Map.Entry<Integer, ConcurrentLinkedQueue<String>>> entries = devicesUploadFileMap.entrySet();
                    if (CollectionUtils.isEmpty(entries)) {
//                        System.out.println("无设备信息.... 无队列信息......");
                        continue;
                    }
                    //一台设备对应一个队列
                    for (Map.Entry<Integer, ConcurrentLinkedQueue<String>> entry : devicesUploadFileMap.entrySet()) {
                        final ConcurrentLinkedQueue<String> valueQueue = entry.getValue();
                        final Integer termSn = entry.getKey();
                        if (CommUtils.isNull(valueQueue) || valueQueue.isEmpty()) {
                            continue;
                        }
                        if (CommUtils.isNull(termSn)) {
                            continue;
                        }
                        //一台设备一个线程 一台设备多个文件......
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                while (true) {
                                    String poll = valueQueue.poll(); //取出队列中的发送报文指令
                                    if (CommUtils.isNull(poll)) {
                                        //结束这个线程......
                                        System.out.println("队列信息为null" + termSn);
                                        break;
                                    }
                                    System.out.println("解析队列参数【" + poll + "】....下发到设备文件上传中...." + termSn);

                                    waiters.put(termSn, Thread.currentThread());
                                    LockSupport.park();//等待当前文件上传成功...挂起状态......
                                    System.out.println(termSn + ":文件上传成功......." + poll);
                                }
                                waiters.remove(termSn);//处理完当前设备后,移除该线程
                                System.out.println("处理完" + termSn);
                            }
                        }).start();

                        devicesUploadFileMap.remove(termSn);
                    }

                }
            }
        }).start();



        Thread.sleep(3000L); // 让前面的线程跑起来

        // 2台设备同时上传文件....
        for (int i = 0; i < 2; i++) {
            final int termSn = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<>();
                        for (int k = 1; k <= 10; k++) {
                            queue.offer("文件" + k);
                        }
                        devicesUploadFileMap.put(termSn, queue);
                        System.out.println(termSn + "塞入完成");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }


        //上传成功通知...
        Thread.sleep(5000L); // 让前面的线程跑起来
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                while (true) {
                    for (int i = 0; i < 2; i++) {
                        Thread.sleep(1000 * 10L); //10秒
                        Thread thread = waiters.get(i);
                        LockSupport.unpark(thread);//
                    }
                }
            }
        }).start();

    }

demo2:

public static  ConcurrentHashMap<Integer, ConcurrentLinkedQueue<String>> devicesUploadFileMap = new ConcurrentHashMap<>();

    public static ConcurrentHashMap<Integer, Thread> waiters = new ConcurrentHashMap<>();

    public static ConcurrentHashMap<Integer, Thread> beingHandlerDevices = new ConcurrentHashMap<>();




    public static void main(String[] args) throws InterruptedException {
        // 监听队列 线程.....
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {

                while (true) { //监听队列中的数据......
                    Thread.sleep(1000L);

                    Set<Map.Entry<Integer, ConcurrentLinkedQueue<String>>> entries = devicesUploadFileMap.entrySet();
                    if (CollectionUtils.isEmpty(entries)) {
//                        System.out.println("无设备信息.... 无队列信息......");
                        continue;
                    }

                    //一台设备对应一个队列
                    for (Map.Entry<Integer, ConcurrentLinkedQueue<String>> entry : devicesUploadFileMap.entrySet()) {
                        final Integer termSn = entry.getKey();
//                        final ConcurrentLinkedQueue queue = entry.getValue();

                        if (CommUtils.isNull(termSn)) {
                            continue;
                        }

                        if (!CommUtils.isNull(beingHandlerDevices.get(termSn))) {
//                            System.out.println("termSn:" + termSn + "正在处理文件.......");
                            continue;
                        }

                        //一台设备一个线程 一台设备多个文件......
                        new Thread(new Runnable() {
                            @Override
                            public void run() {
                                beingHandlerDevices.put(termSn, Thread.currentThread());
                                while (true) {
                                    ConcurrentLinkedQueue<String> queue = devicesUploadFileMap.get(termSn);
                                    String poll = queue.poll(); //取出队列中的发送报文指令
                                    if (CommUtils.isNull(poll)) {
                                        //结束这个线程......
                                        System.out.println("id:" + Thread.currentThread().getId() +
                                                ",name:" + Thread.currentThread().getName() + "队列信息为:null" + termSn);
                                        break;
                                    }
                                    System.out.println("id:" + Thread.currentThread().getId() +
                                            ",name:" + Thread.currentThread().getName() +
                                            "解析队列参数【" + poll + "】....下发到设备文件上传中....termSn:" + termSn);

                                    waiters.put(termSn, Thread.currentThread());
                                    LockSupport.park();//等待当前文件上传成功...挂起状态......

                                    System.out.println("termSn:" + termSn + ":文件上传成功:......." + poll);
                                }

                                waiters.remove(termSn);//处理完当前设备后,移除该线程
                                beingHandlerDevices.remove(termSn); //处理完当前设备后,移除正在处理的termSn
                                devicesUploadFileMap.remove(termSn);//移除设备信息
                                System.out.println("处理完" + termSn);
                            }

                        }).start();

//                        devicesUploadFileMap.remove(termSn);//移除设备信息

                    }


                }
            }
        }).start();



        Thread.sleep(3000L); // 让前面的线程跑起来

        // 2台设备同时上传文件....
        for (int i = 0; i < 2; i++) {
            final int termSn = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        for (int k = 1; k <= 5; k++) {
                            Thread.sleep(3000L); // 让前面的线程跑起来
                            ConcurrentLinkedQueue<String> termSnForQueue = devicesUploadFileMap.get(termSn);
                            if (CommUtils.isNull(termSnForQueue)) {
                                termSnForQueue = new ConcurrentLinkedQueue<>();
                            }
                            termSnForQueue.offer("文件" + k);
                            devicesUploadFileMap.put(termSn, termSnForQueue);
                            System.out.println("termSn:" + termSn + ",塞入第" + k + "文件");
                        }
                        System.out.println(termSn + "塞入完成");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }



        //上传成功通知...
        Thread.sleep(5000L); // 让前面的线程跑起来
        new Thread(new Runnable() {
            @SneakyThrows
            @Override
            public void run() {
                while (true) {
                    for (int i = 0; i < 2; i++) {
                        Thread.sleep(1000 * 10L); //10秒
                        Thread thread = waiters.get(i);
                        LockSupport.unpark(thread);//
                    }
                }
            }
        }).start();

    }

你可能感兴趣的:(实战解决方案)