为什么即使我调用 disruptor.shutdown 我的程序也没有停止
Why doesn't my program stop even when i call disruptor.shutdown
我一直在尝试使用 LMAX 干扰器来缓冲我的一个程序产生的内容,并将它们作为一批记录发布到另一个程序(我仍然无法完成消费者批处理部分)。但即使不使用记录的批处理,它也能正常工作。但我的问题是尽管我曾经调用
`disruptor.shutdown()` and `executorService.shutdownNow()`
如示例之一所示,它不会停止执行程序。它甚至也在这些方法下面执行语句。当我打印
executorService.isShutdown();
它 returns 是的。有人可以帮我解决这个问题吗...
编辑
"pool-1-thread-1" prio=10 tid=0x00007f57581b9800 nid=0x1bec waiting on condition [0x00007f573eb0d000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d9110148> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:45)
at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:55)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
您的 Java 进程仅在所有线程(非守护线程)完成时停止。
可能某些线程仍在 运行,可能处于锁定状态,可能处于循环状态。
要查看仍然是什么线程 运行,您可以使用 jdk-工具:
使用 jps
获取 运行 Java 个进程的 ID:
C:\DVE\jdk\jdk8u45x64\jdk1.8.0_45\bin>jps
4112 TestExMain
使用正确的程序 ID 使用命令 jstack
:
C:\DVE\jdk\jdk8u45x64\jdk1.8.0_45\bin>jstack 4112
2015-09-17 09:12:45
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode):
"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001d208800 nid=0x1b7c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"main" #1 prio=5 os_prio=0 tid=0x0000000002260800 nid=0x1324 waiting on condition [0x000000000224f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.example.TestExMain.main(TestExMain.java:8)
例如,在这里您会看到一个线程 Service Thread
,它是一个守护进程 - 该线程不会阻止您的程序关闭。
Thread main 不是守护线程 - Java-Process 将等待该线程完成,然后才会停止。
对于每个线程,您将看到一个堆栈跟踪,线程所在的位置 - 您可以找到可能使线程远离 运行.
的代码
您拥有的那个特定线程以某种方式被锁定(我不知道为什么,它可能是 wait()
调用、synchronize
块或其他一些锁定机制)。当您调用 disruptor.shutdown()
时该线程没有停止,这可能是您使用的库中的错误。
一些对我有帮助的提示:
1。在 ExecutorService 线程上设置守护进程标志
使用 ThreadFactory
(或 Guava 的 ThreadFactoryBuilder
)执行此操作。
示例:
final ThreadFactory threadFactory =
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
final ThreadFactory threadFactory = Executors.defaultThreadFactory();
final Thread thread = threadFactory.newThread(r);
thread.setDaemon(true);
return thread;
}
};
final ExecutorService executorService =
Executors.newFixedThreadPool(threadCount, threadFactory);
2。关机命令
Disruptor.shutdown(long, TimeUnit)
Disruptor.halt()
ExecutorService.shutdown()
ExecutorService.awaitTermination(long, TimeUnit)
不耐烦关机示例:
try {
disruptor.shutdown(0, TimeUnit.NANOSECONDS);
// if shutdown is successful:
// 1. exception is not thrown (obviously)
// 2. Disruptor.halt() is called automatically (less obvious)
}
catch (TimeoutException e) {
disruptor.halt();
}
executorService.shutdown();
executorService.awaitTermination(0, TimeUnit.NANOSECONDS);
3。使用关机挂钩
即使在调用 System.exit(int)
时也会调用这些函数,但如果您的 JVM 被 SIGKILL
(或非 POSIX 平台上的等效项)杀死,则不会。
Runtime.getRuntime()
.addShutdownHook(
new Thread(
() -> {
// shutdown here
}));
我一直在尝试使用 LMAX 干扰器来缓冲我的一个程序产生的内容,并将它们作为一批记录发布到另一个程序(我仍然无法完成消费者批处理部分)。但即使不使用记录的批处理,它也能正常工作。但我的问题是尽管我曾经调用
`disruptor.shutdown()` and `executorService.shutdownNow()`
如示例之一所示,它不会停止执行程序。它甚至也在这些方法下面执行语句。当我打印
executorService.isShutdown();
它 returns 是的。有人可以帮我解决这个问题吗...
编辑
"pool-1-thread-1" prio=10 tid=0x00007f57581b9800 nid=0x1bec waiting on condition [0x00007f573eb0d000]
java.lang.Thread.State: WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000d9110148> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.park(LockSupport.java:186)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2043)
at com.lmax.disruptor.BlockingWaitStrategy.waitFor(BlockingWaitStrategy.java:45)
at com.lmax.disruptor.ProcessingSequenceBarrier.waitFor(ProcessingSequenceBarrier.java:55)
at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:123)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
您的 Java 进程仅在所有线程(非守护线程)完成时停止。 可能某些线程仍在 运行,可能处于锁定状态,可能处于循环状态。
要查看仍然是什么线程 运行,您可以使用 jdk-工具:
使用 jps
获取 运行 Java 个进程的 ID:
C:\DVE\jdk\jdk8u45x64\jdk1.8.0_45\bin>jps
4112 TestExMain
使用正确的程序 ID 使用命令 jstack
:
C:\DVE\jdk\jdk8u45x64\jdk1.8.0_45\bin>jstack 4112
2015-09-17 09:12:45
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.45-b02 mixed mode):
"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x000000001d208800 nid=0x1b7c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"main" #1 prio=5 os_prio=0 tid=0x0000000002260800 nid=0x1324 waiting on condition [0x000000000224f000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at com.example.TestExMain.main(TestExMain.java:8)
例如,在这里您会看到一个线程 Service Thread
,它是一个守护进程 - 该线程不会阻止您的程序关闭。
Thread main 不是守护线程 - Java-Process 将等待该线程完成,然后才会停止。
对于每个线程,您将看到一个堆栈跟踪,线程所在的位置 - 您可以找到可能使线程远离 运行.
您拥有的那个特定线程以某种方式被锁定(我不知道为什么,它可能是 wait()
调用、synchronize
块或其他一些锁定机制)。当您调用 disruptor.shutdown()
时该线程没有停止,这可能是您使用的库中的错误。
一些对我有帮助的提示:
1。在 ExecutorService 线程上设置守护进程标志
使用 ThreadFactory
(或 Guava 的 ThreadFactoryBuilder
)执行此操作。
示例:
final ThreadFactory threadFactory =
new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
final ThreadFactory threadFactory = Executors.defaultThreadFactory();
final Thread thread = threadFactory.newThread(r);
thread.setDaemon(true);
return thread;
}
};
final ExecutorService executorService =
Executors.newFixedThreadPool(threadCount, threadFactory);
2。关机命令
Disruptor.shutdown(long, TimeUnit)
Disruptor.halt()
ExecutorService.shutdown()
ExecutorService.awaitTermination(long, TimeUnit)
不耐烦关机示例:
try {
disruptor.shutdown(0, TimeUnit.NANOSECONDS);
// if shutdown is successful:
// 1. exception is not thrown (obviously)
// 2. Disruptor.halt() is called automatically (less obvious)
}
catch (TimeoutException e) {
disruptor.halt();
}
executorService.shutdown();
executorService.awaitTermination(0, TimeUnit.NANOSECONDS);
3。使用关机挂钩
即使在调用 System.exit(int)
时也会调用这些函数,但如果您的 JVM 被 SIGKILL
(或非 POSIX 平台上的等效项)杀死,则不会。
Runtime.getRuntime()
.addShutdownHook(
new Thread(
() -> {
// shutdown here
}));