问题描述:

  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

was控制台无法停止应用的更多相关文章

  1. WEBLOGIC启动后,重启后控制台进入缓慢、延迟,探查WEBLOGIC

    本文说的是解决过程,可直接点击本行略过探查内容,跳到最后的解决办法!! 现象: 1.WEBLOGIC安装在 CENTOSopenSUSE 等LINUX或者UNIX机器上,无论是虚拟机或者PC或者服务器 ...

  2. WCF学习笔记1--发布使用配置文件的服务

    关于WCF的入门网上资料很多,可以参考蒋金楠老师的博客http://www.cnblogs.com/artech/archive/2007/02/26/656901.html,我是从这篇博客开始学习的 ...

  3. [置顶] Weblogic节点管理

    配置节点管理之后能方便管理,可以在控制台启动停止被管服务器,一般配置步骤:创建受管服务器,创建machine,屏蔽SSL主机名验证,修改nodemanager.properties,启动nodeman ...

  4. ubuntu上的mysql数据库双机备份设置

    配置环境: myslq 5.5.3 + ubuntu server 12.04 一.配置MySQL主服务器(192.168.0.1) 1.增加一个账号专门用于同步 1 mysql>grant r ...

  5. Maven注意事项

    Maven好处: 1.依赖管理:对jar包统一管理 2.项目构建:项目编码完成后,对项目进行编译.测试.打包.部署,实现项目一键发布1.配置环境变量    注意:maven工具必须有jdk环境.并且: ...

  6. zookeeper初探

    安装三台linux虚拟机,安装好java环境,并配置好网络以及host文件,分别改好hostname为node0.node1.node2 上传下载好的zookeeper文件到node0的/usr/lo ...

  7. vue-cli webpack 全局引用jquery

    一.初始化项目 首先,执行vue init webpack F:\ZhaoblTFS\Zeroes\Document\代码示例\vue-cli-webpack-jquery>vue init w ...

  8. weblogic——服务器搭建与配置

    本次操作的内容:weblogic服务器搭建与配置服务 本次操作是主要围绕如何搭建weblogic服务器及配置服务,总共有两大步骤,可划分为六个小步骤: 选取已有环境,准备weblogic压缩包 安装w ...

  9. weblogic重启脚本

    客户要求每周weblogic重启,每台机器上有多个weblogic实例,开始准备单个服务器实例做成sysv风格的脚本,但是实例较多,于是在满足需求和自动化重启的情况下,多个服务器实例的重启放在了一起, ...

随机推荐

  1. rand随机函数

    1.rand() rand()函数是使用线性同余法做的,它并不是真的随机数,因为其周期特别长,所以在一定范围内可以看成随机的. rand()函数不需要参数,它将会返回0到RAND_MAX之间的任意的整 ...

  2. Docs-.NET-C#-指南-语言参考-预处理器指令:#warning(C# 参考)

    ylbtech-Docs-.NET-C#-指南-语言参考-预处理器指令:#warning(C# 参考) 1.返回顶部 1. #warning(C# 参考) 2015/07/20 #warning 允许 ...

  3. 阿里云RDS与ECS服务器数据库做主从

    阿里云RDS与ECS服务器数据库做主从 [精] 里云RDS(数据库)基于飞天大规模分布式计算和存储能力,提供超高性价比的单机版实例,同时利用读写分离横向扩展读能力,满足网站类的业务需求.提供稳定.高性 ...

  4. 你真的懂wait、notify和notifyAll吗

    生产者消费者模型是我们学习多线程知识的一个经典案例,一个典型的生产者消费者模型如下: public void produce() { synchronized (this) { while (mBuf ...

  5. osg 自定义图元

    osg::ref_ptr<osg::Geode> OSG_Qt_::createBox() { osg::ref_ptr<osg::Geode> osg_geode = new ...

  6. 【AI教育】可以看看行业痛点分析

    http://www.woshipm.com/it/2801582.html 至于解决方案嘛,还在堆砌技术的阶段.

  7. ElasticSearch——路由(_routing)机制

    前言 一条数据是如何落地到对应的shard上的? 当索引一个文档的时候,文档会被存储到一个主分片中. Elasticsearch 如何知道一个文档应该存放到哪个分片中呢? 首先这肯定不会是随机的,否则 ...

  8. 原创:Mac AppleScript 自动登录两个QQ

    前提,已有登录过的账号,且没有设置为自动登录 tell application "QQ" activate tell application "System Events ...

  9. Docker 容器的运行(八)

    目录 一.运行容器 1.运行第一个容器 2.让容器长期运行 二.进入容器 1.attach 2.exec 3.attach VS exec 4.容器内部都在干些什么 三.停止/启动/重启容器 四.暂停 ...

  10. IO-file-07 递归

    package com.bwie.io; /** * 递归: * 方法自己调用自己 * 递归头:何时结束递归 * 递归体:重复调用 * @author Allen17805272076 * */ pu ...