4번독수리의 둥지
Java Thread state, thread dump 본문
Java Thread state
- NEW : 스레드 객체가 생성된 직후
- RUNNABLE : CPU 점유중
- BLOCKED : monitor lock을 점유하기 위해 block되었음
- WAITING : I/O, wait() 등으로 wait
- TIMED_WAITING : timeout이 주어진 waiting
- TERMINATED : 종료
thread dump 얻기
- jps
- jstack
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.State.html
https://d2.naver.com/helloworld/10963
문제가 된 코드
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ServiceDiscovery {
private ScheduledFuture<?> seviceDiscovery = null;
void run() {
seviceDiscovery = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
}).scheduleAtFixedRate(() -> {
fullNetworkDiscovery(true);
}, SERVICE_DISCOVER_FREQ_SECONDS, SERVICE_DISCOVER_FREQ_SECONDS, TimeUnit.SECONDS);
}
void shutdown() {
try {
final ScheduledFuture<?> lseviceDiscovery = seviceDiscovery;
seviceDiscovery = null;
if (null != lseviceDiscovery) {
lseviceDiscovery.cancel(true);
}
} catch (Exception e) {
logger.error(e);
}
}
}
수정
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
public class ServiceDiscovery {
private ScheduledFuture<?> seviceDiscovery = null;
private transient ScheduledExecutorService serviceDiscoveryExecutorService;
void run() {
serviceDiscoveryExecutorService = Executors.newSingleThreadScheduledExecutor(r -> {
Thread t = Executors.defaultThreadFactory().newThread(r);
t.setDaemon(true);
return t;
});
seviceDiscovery = serviceDiscoveryExecutorService.scheduleAtFixedRate(() -> {
fullNetworkDiscovery(true);
}, SERVICE_DISCOVER_FREQ_SECONDS, SERVICE_DISCOVER_FREQ_SECONDS, TimeUnit.SECONDS);
}
void shutdown() {
try {
final ScheduledFuture<?> lseviceDiscovery = seviceDiscovery;
seviceDiscovery = null;
if (null != lseviceDiscovery) {
lseviceDiscovery.cancel(true);
}
ScheduledExecutorService lsde = serviceDiscoveryExecutorService;
serviceDiscoveryExecutorService = null;
if (null != lsde) {
lsde.shutdownNow();
}
} catch (Exception e) {
logger.error(e);
}
}
}
참고
https://jira.hyperledger.org/browse/FABJ-389
더 공부...
Executors
Executors.newSingleThreadScheduledExecutor()
Executors.defaultThreadFactory()
ThreadFactory.newThread()
Thread.setDaemon()
ScheduledExecutorService
ScheduledExecutorService.scheduleAtFixedRate()
ScheduledFuture
Thread.setDaemon
Future.cancel()
Attempts to cancel execution of this task. This attempt will fail if the task has already completed, has already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.
After this method returns, subsequent calls to isDone will always return true. Subsequent calls to isCancelled will always return true if this method returned true.
-
Parameters:
- mayInterruptIfRunning true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete
-
Returns:
- false if the task could not be cancelled, typically because it has already completed normally; true otherwise
ExecutorService.shutdownNow()
Attempts to stop all actively executing tasks, halts the processing of waiting tasks, and returns a list of the tasks that were awaiting execution.
This method does not wait for actively executing tasks to terminate. Use awaitTermination to do that.
There are no guarantees beyond best-effort attempts to stop processing actively executing tasks. For example, typical implementations will cancel via Thread.interrupt, so any task that fails to respond to interrupts may never terminate.
-
Returns:
- list of tasks that never commenced execution
-
Throws:
- SecurityException - if a security manager exists and shutting down this ExecutorService may manipulate threads that the caller is not permitted to modify because it does not hold java.lang.RuntimePermission("modifyThread"), or the security manager's checkAccess method denies access.