zoukankan      html  css  js  c++  java
  • was控制台无法停止应用

    问题描述:

      was控制台无法停止应用,只能通过停止server的方式停止;

    代码实现:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.util.concurrent.LinkedBlockingQueue;
    
    /**
     * @className MessageReceiver
     * @Desc 消息接收处理
     * @Author HZ
     * @Date 2019/11/25 9:39
     * @Version 1.0
     */
    public class MessageReceiver implements Runnable{
    
        private final static Logger LOGGER = LoggerFactory.getLogger(MessageReceiver.class);
    
        /**
         * 通信消息队列
         * */
        private LinkedBlockingQueue<String> messageQueue = new LinkedBlockingQueue<>();
    
        /**
         * 线程名
         * */
        private final static String threadName = "MessageReceiver";
    
        /**
         * 运行标志
         * */
        private volatile boolean isRunning = true;
    
        /**
         * 线程
         * */
        private Thread messageQueueThread;
    
        /**
         * 锁 用作休眠与唤醒
         * */
        private Object lock = new Object();
    
        /**
         * @title
         * @Description 初始化
         * @Author HZ
         * @Param
         * @Return
         * @Date: 2019/11/25 10:59
         */
        public void init(){
            this.messageQueueThread = new Thread(this, threadName);
            this.messageQueueThread.start();
        }
    
        /**
         * @title destory
         * @Description 停止时销毁
         *  lock.notifyAll();先唤醒messageQueueThread线程!!!
         *  this.messageQueueThread.join();等待messageQueueThread线程执行完
         * @Author HZ
         * @Param []
         * @Return void
         * @Date: 2019/11/25 10:59
         */
        public void destory(){
            this.isRunning = false;
    
            synchronized (lock) {
                lock.notifyAll();
                LOGGER.info("强制唤醒messageQueueThread");
            }
    
            if (this.messageQueueThread != null) {
                try {
                    this.messageQueueThread.join();
                } catch (InterruptedException e) {
                    LOGGER.info("线程关闭失败...错误信息={}", e);
                }
            }
            LOGGER.info("destroy MessageDatacommReceiver success");
        }
    
        /**
         * @title pushIntoQueue
         * @Description 把对象放入队列
         * @Author HZ
         * @Param [str]
         * @Return void
         * @Date: 2019/11/25 11:01
         */
        public void pushIntoQueue(String str){
            try {
                synchronized (lock) {
                    this.messageQueue.put(str);
                    LOGGER.debug("开始唤醒messageQueueThread线程");
                    lock.notifyAll();
                }
            } catch (InterruptedException e) {
                LOGGER.error("把对象放入队列...错误信息={}", e);
            }
        }
    
        /**
         * @title run
         * @Description 线程主方法
         * @Author HZ
         * @Param []
         * @Return void
         * @Date: 2019/11/25 11:01
         */
        @Override
        public void run(){
            while(this.isRunning){
                try {
                    synchronized (lock) {
                        if(this.messageQueue.isEmpty()){
                            lock.wait();
                            LOGGER.debug("messageQueueThread线程被唤醒");
                        }else{
                            //TODO 业务方法
                        }
                    }
                }catch (Exception e) {
                    // 捕获异常,防止线程死掉
                    LOGGER.error("messageQueueThread发生未预计的异常", e);
                }
            }
        }
    }

    功能描述:

      实例化MessageReceiver类时调用init()方法,创建并启动一个线程messageQueueThread

      messageQueueThread线程的停止依靠运行标记isRunning控制

      生产者通过调用pushIntoQueue方法将待处理事件放入到阻塞队列messageQueue, 同时调用notifyAll通知messageQueueThread取获取数据

      messageQueueThread循环从阻塞队列messageQueue中获取数据,没有获取到值则调用wait方法阻塞 MessageReceiver对象销毁时调用destory方法

    问题原因:

      destory()中没有调用lock.notifyAll();这段代码

      导致调用this.messageQueueThread.join();方法时messageQueueThread一直阻塞没有执行,该对象也就无法销毁,资源无法释放

            synchronized (lock) {
                lock.notifyAll();
                LOGGER.info("强制唤醒messageQueueThread");
            }

    参考文档:

    https://www.cnblogs.com/yanze/p/10032363.html

    https://blog.csdn.net/jiangguilong2000/article/details/11617529

  • 相关阅读:
    什么是web标准
    Axure 快捷方式
    asp.net mvc4中model与Model的区别
    Git 操作常用命令
    ASP.NET MVC 中@html.ActionLink的几种参数格式
    Datagridview控件实现分页功能
    winform 拖动无边框窗体(调用Windows API)
    利用C#轻松创建不规则窗体
    Linq to sql 操作
    第一篇博客,写些学习感想
  • 原文地址:https://www.cnblogs.com/lyrb/p/11926752.html
Copyright © 2011-2022 走看看