我正在运行简单的thread
,该方法如下所示
public run()
while(!stopFlag){
// print something Line 1
// print something Line 2
// print something Line 3
// print something Line 4
}
如果我在ExecutorService
viz中运行这个线程
ExecutorService exs = Executors.newFixedThreadPool(5);
exs.execute(new MyThread));
我阻止了ExecutorService
exs.shutdown();
但是这并不会停止线程,因为标志没有设置为false。在另一个与同一主题有关的问题中,我被要求正确处理InterruptedException,这是在调用exs.shutdown()时引起的。但在这种情况下,我不做任何可以抛出InterruptedException的操作。
处理这类案件的标准方法是什么?
进一步问了沙比尔的答案:“如果你的可运行程序对中断没有很好的响应,除了关闭JVM之外,什么也不能阻止它。".This似乎就是我的情况。
但是如何介绍InterruptedException的处理;如果我没有调用任何抛出中断异常的方法?
发布于 2017-05-16 06:56:58
如果您愿意关闭您的线程,即使该标志仍然为真,则应使用- ExecutorService.shutdownNow()
方法而不是ExecutorService.shutdown()
。
引用Java文档,
shutdown()
启动有序关机,执行以前提交的任务,但不接受任何新任务。如果已经关闭,则调用没有其他效果。 此方法不等待以前提交的任务完成执行。使用awaitTermination来完成这个任务。
shutdownNow()
尝试停止所有正在执行的任务,停止等待任务的处理,并返回等待执行的任务列表。 此方法不等待主动执行任务终止。使用awaitTermination来完成这个任务。 除了尽力停止处理积极执行的任务之外,没有任何保证。例如,典型的实现将通过Thread.interrupt取消,因此任何无法响应中断的任务都可能永远不会终止。
对于标准方式,我将引用来自ExecutorService
接口的JDK示例,
使用示例
Here is a sketch of a network service in which threads in a thread pool service incoming requests. It uses the preconfigured Executors.newFixedThreadPool factory method: class NetworkService implements Runnable { private final ServerSocket serverSocket; private final ExecutorService pool;
public NetworkService(int port, int poolSize)
throws IOException {
serverSocket = new ServerSocket(port);
pool = Executors.newFixedThreadPool(poolSize); }
public void run() { // run the service
try {
for (;;) {
pool.execute(new Handler(serverSocket.accept()));
}
} catch (IOException ex) {
pool.shutdown();
} } }
class Handler implements Runnable { private final Socket socket; Handler(Socket socket) { this.socket = socket; } public void run() {
// read and service request on socket } }} The following method shuts down an ExecutorService in two phases, first by calling shutdown to reject incoming tasks, and then calling shutdownNow, if necessary, to cancel any lingering tasks: void shutdownAndAwaitTermination(ExecutorService pool) { pool.shutdown(); // Disable new tasks from being submitted try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
} } catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt(); } }}
请注意,即使使用shutdownNow()
也没有保证。
编辑:,如果我将您的while(!stopFlag)
更改为while(!Thread.currentThread().isInterrupted())
,那么有条件循环的线程可以使用shutdownNow()
关闭,而不是使用shutdown()
,这样线程就会被shutdownNow()
中断。我使用的是JDK8和Windows8.1。我必须在主线程中放置一个睡眠,这样服务才能有时间设置服务并启动可运行的。线程启动,然后进入,然后在调用shutdownNow()
时停止。我不理解shutdown()
的这种行为,即线程永远不会从while循环中出来。因此,让您的运行表负责中断的方法应该存在,要么检查标志,要么处理异常。如果您的runnable对中断没有很好的响应,那么除了关闭JVM之外,什么也不能阻止它。
这里展示了一个很好的方法
发布于 2017-05-16 10:46:05
好吧,从你的问题中,我假设你正试图优雅地关闭这个过程。为了做到这一点,您需要注册一个shutdownHook来实现它。这里有一个实现它的示例代码。
package com.example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadManager {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Runtime.getRuntime().addShutdownHook(new Thread(){
MyThread myThread = null;
@Override
public void run(){
System.out.println("Shutting down....");
this.myThread.stopProcess();
}
public Thread setMyThread(MyThread myThread){
this.myThread=myThread;
return this;
}
}.setMyThread(myThread));
ExecutorService exs = Executors.newFixedThreadPool(5);
myThread.setName("User");
exs.execute(myThread);
exs.shutdownNow();
}
}
在MyThread.java中会出现以下情况:-
package com.example;
public class MyThread extends Thread{
private boolean stopFlag;
@Override
public void run(){
while(!stopFlag){
System.out.println(this.getName());
}
}
public void stopProcess(){
this.stopFlag=true;
}
}
现在,如果您使用此代码生成一个jar文件,并在Linux服务器中运行该文件以查看其工作方式,那么请遵循以下附加步骤
Step 1> nohup java -jar MyThread.jar &
按ctrl+c以存在,现在使用以下命令查找pid
Step 2> ps -ef| grep MyThread.jar
一旦得到pid,就执行以下命令以优雅地停止
Step 3>kill -TERM <Your PID>
当您检查nohub.out文件时,输出如下所示
User
User
.
.
.
User
Shutting down....
User
.
.
记住,如果您试图使用杀死-9关闭,您将永远不会看到Shutting down....
消息。
@沙比尔已经讨论了shutdown
和shutdownNow
之间的区别。但是,我永远不会建议您在线程运行时使用interrupt
调用。这可能会导致实时环境中的内存泄漏。
Upadte 1:-
public static void main(String[] args) {
MyThread myThreads[] = new MyThread[5];
ExecutorService exs = Executors.newFixedThreadPool(5);
for(int i=0;i<5;++i){
MyThread myThread = new MyThread();
myThread.setName("User "+i);
exs.execute(myThread);
myThreads[i] = myThread;
}
Runtime.getRuntime().addShutdownHook(new Thread(){
MyThread myThreads[] = null;
@Override
public void run(){
System.out.println("Shutting down....");
for(MyThread myThread:myThreads){
myThread.stopProcess();
}
}
public Thread setMyThread(MyThread[] myThreads){
this.myThreads=myThreads;
return this;
}
}.setMyThread(myThreads));
exs.shutdownNow();
}
https://stackoverflow.com/questions/43993505
复制相似问题