问题描述:

  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. 阶段5 3.微服务项目【学成在线】_day17 用户认证 Zuul_16-网关-过虑器

    4.5 过虑器 Zuul的核心就是过虑器,通过过虑器实现请求过虑,身份校验等. 4.5.1 ZuulFilter 自定义过虑器需要继承 ZuulFilter,ZuulFilter是一个抽象类,需要覆盖 ...

  2. Qt编写Onvif搜索及云台控制工具

    一.前言 这个工具很早以前大概在2013年就想做了,后面杂七杂八的事情一再耽搁,记得当时最初用的是soap类来搜索和解析的,后面发现太大了,每次编译都要等好久,光源码文件加起来都快10MB了,而且函数 ...

  3. react 问题记录三

    7.三元表达式 是否显示提交按钮(值运算用一对大括号包起来): {this.state.isTrue ? <FormItem style={{textAlign: 'right',marginT ...

  4. ELK之在CentOS7.5上使用rpm包安装配置ELK7版本

    一,安装环境查看 二,软件版本选用 jdk 1.8.0_171 elasticsearch 7.1.1 kibana 7.1.1 logstash 7.1.1 三,安装配置 1,安装JDK 过程不详述 ...

  5. 【c# 学习笔记】c#中的语句

    1.条件语句: if语句: bool condition = true; if (condition) { } else if (condition) { } else { } switch语句: b ...

  6. Object.defineProperty()方法学习笔记

    这是js中一个非常重要的方法,ES6中某些方法的实现依赖于它,VUE通过它实现双向绑定 此方法会直接在一个对象上定义一个新属性,或者修改一个已经存在的属性, 并返回这个对象 参数 Object.def ...

  7. C#数字除法

    C#中计算double a=1/1000:应该结果是0.001,但为什么会变成0呢? C# 中 如果相除的两个数都是整数(int 型) 那么除的结果就是只取整数部分 所以你才会取到0 如果你要取精确的 ...

  8. php csv 简单的导入

    if($act == 'user_upload_do'){ global $db; $filename = $_FILES['file']['tmp_name']; if (empty ($filen ...

  9. execl文件读取封装

    前言:做自动化常用的公共方法 注:第一次使用记得先 pip install xlrd 模块import xlrd class ReadExecl(): def __init__(self,filena ...

  10. FCM实现手机推送,推送的方式,真机调试

    FCM实现手机 1 下载Androidstudio 3.2 版本,之后新建一个项目 2  创建完项目之后查找文件AndroidMainifest.xml 3  访问网站注册一个自己的firebase的 ...