Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Apache RocketMQ
Rocketmq
提交
e3f4251c
R
Rocketmq
项目概览
Apache RocketMQ
/
Rocketmq
上一次同步 大约 3 年
通知
267
Star
16139
Fork
68
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
Rocketmq
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
e3f4251c
编写于
3月 06, 2017
作者:
Y
yukon
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[ROCKETMQ-119] Add ThreadUtils and shutdown PullMessageService properly
上级
53b98d0d
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
181 addition
and
0 deletion
+181
-0
client/src/main/java/org/apache/rocketmq/client/impl/consumer/PullMessageService.java
...che/rocketmq/client/impl/consumer/PullMessageService.java
+7
-0
common/src/main/java/org/apache/rocketmq/common/utils/ThreadUtils.java
...in/java/org/apache/rocketmq/common/utils/ThreadUtils.java
+174
-0
未找到文件。
client/src/main/java/org/apache/rocketmq/client/impl/consumer/PullMessageService.java
浏览文件 @
e3f4251c
...
...
@@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
import
org.apache.rocketmq.client.impl.factory.MQClientInstance
;
import
org.apache.rocketmq.client.log.ClientLogger
;
import
org.apache.rocketmq.common.ServiceThread
;
import
org.apache.rocketmq.common.utils.ThreadUtils
;
import
org.slf4j.Logger
;
public
class
PullMessageService
extends
ServiceThread
{
...
...
@@ -97,6 +98,12 @@ public class PullMessageService extends ServiceThread {
log
.
info
(
this
.
getServiceName
()
+
" service end"
);
}
@Override
public
void
shutdown
(
boolean
interrupt
)
{
super
.
shutdown
(
interrupt
);
ThreadUtils
.
shutdownGracefully
(
this
.
scheduledExecutorService
,
1000
,
TimeUnit
.
MILLISECONDS
);
}
@Override
public
String
getServiceName
()
{
return
PullMessageService
.
class
.
getSimpleName
();
...
...
common/src/main/java/org/apache/rocketmq/common/utils/ThreadUtils.java
0 → 100644
浏览文件 @
e3f4251c
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package
org.apache.rocketmq.common.utils
;
import
java.util.concurrent.BlockingQueue
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.ThreadFactory
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
java.util.concurrent.TimeUnit
;
import
java.util.concurrent.atomic.AtomicInteger
;
import
org.apache.rocketmq.common.constant.LoggerName
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
final
class
ThreadUtils
{
private
static
final
Logger
log
=
LoggerFactory
.
getLogger
(
LoggerName
.
TOOLS_LOGGER_NAME
);
public
static
ExecutorService
newThreadPoolExecutor
(
int
corePoolSize
,
int
maximumPoolSize
,
long
keepAliveTime
,
TimeUnit
unit
,
BlockingQueue
<
Runnable
>
workQueue
,
String
processName
,
boolean
isDaemon
)
{
return
new
ThreadPoolExecutor
(
corePoolSize
,
maximumPoolSize
,
keepAliveTime
,
unit
,
workQueue
,
newThreadFactory
(
processName
,
isDaemon
));
}
public
static
ExecutorService
newSingleThreadExecutor
(
String
processName
,
boolean
isDaemon
)
{
return
Executors
.
newSingleThreadExecutor
(
newThreadFactory
(
processName
,
isDaemon
));
}
public
static
ScheduledExecutorService
newSingleThreadScheduledExecutor
(
String
processName
,
boolean
isDaemon
)
{
return
Executors
.
newSingleThreadScheduledExecutor
(
newThreadFactory
(
processName
,
isDaemon
));
}
public
static
ScheduledExecutorService
newFixedThreadScheduledPool
(
int
nThreads
,
String
processName
,
boolean
isDaemon
)
{
return
Executors
.
newScheduledThreadPool
(
nThreads
,
newThreadFactory
(
processName
,
isDaemon
));
}
public
static
ThreadFactory
newThreadFactory
(
String
processName
,
boolean
isDaemon
)
{
return
newGenericThreadFactory
(
"Remoting-"
+
processName
,
isDaemon
);
}
public
static
ThreadFactory
newGenericThreadFactory
(
String
processName
)
{
return
newGenericThreadFactory
(
processName
,
false
);
}
public
static
ThreadFactory
newGenericThreadFactory
(
String
processName
,
int
threads
)
{
return
newGenericThreadFactory
(
processName
,
threads
,
false
);
}
public
static
ThreadFactory
newGenericThreadFactory
(
final
String
processName
,
final
boolean
isDaemon
)
{
return
new
ThreadFactory
()
{
private
AtomicInteger
threadIndex
=
new
AtomicInteger
(
0
);
@Override
public
Thread
newThread
(
Runnable
r
)
{
Thread
thread
=
new
Thread
(
r
,
String
.
format
(
"%s_%d"
,
processName
,
this
.
threadIndex
.
incrementAndGet
()));
thread
.
setDaemon
(
isDaemon
);
return
thread
;
}
};
}
public
static
ThreadFactory
newGenericThreadFactory
(
final
String
processName
,
final
int
threads
,
final
boolean
isDaemon
)
{
return
new
ThreadFactory
()
{
private
AtomicInteger
threadIndex
=
new
AtomicInteger
(
0
);
@Override
public
Thread
newThread
(
Runnable
r
)
{
Thread
thread
=
new
Thread
(
r
,
String
.
format
(
"%s_%d_%d"
,
processName
,
threads
,
this
.
threadIndex
.
incrementAndGet
()));
thread
.
setDaemon
(
isDaemon
);
return
thread
;
}
};
}
/**
* Create a new thread
*
* @param name The name of the thread
* @param runnable The work for the thread to do
* @param daemon Should the thread block JVM stop?
* @return The unstarted thread
*/
public
static
Thread
newThread
(
String
name
,
Runnable
runnable
,
boolean
daemon
)
{
Thread
thread
=
new
Thread
(
runnable
,
name
);
thread
.
setDaemon
(
daemon
);
thread
.
setUncaughtExceptionHandler
(
new
Thread
.
UncaughtExceptionHandler
()
{
public
void
uncaughtException
(
Thread
t
,
Throwable
e
)
{
log
.
error
(
"Uncaught exception in thread '"
+
t
.
getName
()
+
"':"
,
e
);
}
});
return
thread
;
}
/**
* Shutdown passed thread using isAlive and join.
*
* @param t Thread to stop
*/
public
static
void
shutdownGracefully
(
final
Thread
t
)
{
shutdownGracefully
(
t
,
0
);
}
/**
* Shutdown passed thread using isAlive and join.
*
* @param millis Pass 0 if we're to wait forever.
* @param t Thread to stop
*/
public
static
void
shutdownGracefully
(
final
Thread
t
,
final
long
millis
)
{
if
(
t
==
null
)
return
;
while
(
t
.
isAlive
())
{
try
{
t
.
interrupt
();
t
.
join
(
millis
);
}
catch
(
InterruptedException
e
)
{
Thread
.
currentThread
().
interrupt
();
}
}
}
/**
* An implementation of the graceful stop sequence recommended by
* {@link ExecutorService}.
*
* @param executor executor
* @param timeout timeout
* @param timeUnit timeUnit
*/
public
static
void
shutdownGracefully
(
ExecutorService
executor
,
long
timeout
,
TimeUnit
timeUnit
)
{
// Disable new tasks from being submitted.
executor
.
shutdown
();
try
{
// Wait a while for existing tasks to terminate.
if
(!
executor
.
awaitTermination
(
timeout
,
timeUnit
))
{
executor
.
shutdownNow
();
// Wait a while for tasks to respond to being cancelled.
if
(!
executor
.
awaitTermination
(
timeout
,
timeUnit
))
{
log
.
warn
(
String
.
format
(
"%s didn't terminate!"
,
executor
));
}
}
}
catch
(
InterruptedException
ie
)
{
// (Re-)Cancel if current thread also interrupted.
executor
.
shutdownNow
();
// Preserve interrupt status.
Thread
.
currentThread
().
interrupt
();
}
}
/**
* A constructor to stop this class being constructed.
*/
private
ThreadUtils
()
{
// Unused
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录