2010-07-13 2 views
9

끝내지 않은 Java 응용 프로그램이 있습니다. main 메서드는 끝나지 만 스레드는 활성 상태로 유지되고 응용 프로그램은 종료되지 않습니다. 문제는 모니터 잠금/대기가 나타나지 않아 종료되지 않는 이유를 알 수 없습니다. 이클립스에 따르면, 나는 2 개의 비 데몬 스레드가 남아있다. 하나는 [DestroyJavaVM]이라고 표시되어 있습니다 (희망이있는 것처럼 보입니다). 다른 하나는 Unsafe.park(boolean, long)에서 차단 된 것 같습니다. 어떻게/어디서 조사해야합니까?끝내지 않을 Java 프로세스를 조사하려면 어디에서 시작해야합니까?

두 번째 스레드의 축소 된 스택 트레이스는 다음과 같습니다

Unsafe.park(boolean, long) 
at LockSupport.park(Object) 
at AbstractQueuedSynchronizer$ConditionObject.await() 
at LinkedBlockingQueue<E>.take() 
at ThreadPoolExecutor.getTask() 
at ThreadPoolExecutor$Worker.run() 
at Thread.run() 
+0

Unsafe.park()에있는 스레드의 전체 스택 추적은 무엇입니까? –

+0

ThreadSoolExecutor.getTask() -> ThreadPoolExecutor $ Worker.run() -> LockSupport.park (Object) -> AbstractQueuedSynchronizer $ ConditionObject.await() -> LinkedBlockingQueue .take() -> 스레드.run() – JenFallow

+0

코드 블록에서 읽는 것이 훨씬 쉽고 질문 자체에서 중요한 부분을 차지하기 때문에 질문에 대한 의견을 수정했습니다. –

답변

0

스레드 덤프와 디버거 내 추측 일 것이다.

0

응용 프로그램의 크기가 확실하지 않지만 만든 모든 스레드를 확인하고 응용 프로그램 실행이 끝나면 실행 방법이 정상적으로 종료되는지 확인합니다. 무서운 들리는 이름에도 불구하고, 일반적으로 특히 전화를 차단하는 모든 종류의 (새로운 (틱에 그) java.util.concurrent에 의해 사용되는,

public void run() { 
    while(true) { //"true" or some condition that never gets a chance to be false 
     //do thread related work 
    } 
} 
0

Unsafe.park : 어딘가에, 스레드 내에서, 당신의 라인을 따라 코드가있을 수 있습니다 꾸러미).

스택을 몇 프레임 아래로 보면 (즉, 일부 JDK 라이브러리 클래스)과 com.example.myapp.MyClass.getNextJob (라이브러리 클래스를 사용하는 클래스)이 표시됩니다.

내가 추측 할 위험이 있다면, 당신이 영원히 차단하는 어떤 종류의 호출을하고 있다고 말하고 싶습니다. 그래서 더 이상 반환 할 것이 없을 때,이 스레드는 "다음"항목을 ​​기다리고 있습니다. . 일종의 "완료"플래그를 설정 한 다음 대기중인 스레드를 인터럽트하거나 차단 호출에 시간 초과를 지정하여 플래그를 확인하여이를 해결할 수 있습니다. 귀하의 코드에 따라 이들 또는 대안 중 하나가 가능할 수 있지만, 바라건대 이것은 당신을 시작하기에 충분합니다.

편집 : 실행 추적 서비스를 종료해야하는 스택 추적을보고 난 후 finnw is right.

1

당신은 당신의 ExecutorService 스레드를 종료하는 두 가지 중 하나를 수행해야합니다. (Guava에서 ThreadFactoryBuilder 클래스이 쉽게 할 것이다)

  1. 데몬 스레드를 생성하는 ThreadFactory 지정에
  2. 전화 shutdown() 당신의 응용 프로그램 종료의 일부로 ExecutorService을 입력하십시오 (예 : main 메서드 끝).
+0

+1 :'shutdown()'이이를 수행 할 수있는 표준 방법입니다. 데몬 스레드는이 문제를 방지 할 수 있지만 원하는 것이 아니며 나중에 문제가 될 수도 있습니다. –

0

귀하의 작업은 다음과 같습니다. 대기열에서 데이터 대기를 차단했습니다. 테이크에는 타임 아웃이 없습니다.

작업 스레드가 생성되면 참조를 유지하십시오. 종료시에 스레드의 인터럽트 메소드를 호출하십시오. InterruptedException이 잡히면 종료하기 위해 호출하는 작업 처리 루프를 수정해야 할 수도 있습니다.

관련 문제