问题描述:
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