동기화된 목록에 액세스하려고 하면 스레드가 중지되는 이유는 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1824768

  •  22-07-2019
  •  | 
  •  

문제

어떤 이유에서인지 결과는 다음과 같습니다.

 public void msgNeedParts() {
    // Blabla...
    System.out.println(name + ": Try to print 'tasks'...");
    synchronized(tasks) {
        System.out.println(name + ": Tasks--" + tasks);
        System.out.println(name + ": Did I manage to print it?");
        tasks.add(new BinToDump(feeder, binNum));
    }
    stateChanged();
 }

그냥 "GantryAgent:'작업'...'을 인쇄해 보지만 다음 메시지는 인쇄하지 마세요.동기화된 목록 '작업'에 액세스하려고 할 때 스레드가 어떻게든 '멈춘 것'인 것 같지만 왜 이런 일이 발생하는지 모르겠습니다.

'tasks'는 다음과 같이 선언되고 초기화되었습니다.

private List<BinToDump> tasks = 
    Collections.synchronizedList(new ArrayList<BinToDump>());

내가 놓친 부분을 지적할 수 있는 사람이 있나요?

아!나에게 범인이 있을 수 있다고 생각합니다.

    /* If nothing left to do, return to original position. */

    synchronized (tasks) {

        if (tasks.isEmpty()) {

            doReturnToOriginalPos();

        }

    }

내 스케줄러(에이전트 디자인)에서 'tasks'가 비어 있는지 확인한 다음 doReturnToOriginalPos()를 호출합니다.어쩌면 이런 일이 계속해서 너무 빨리 일어나서 다른 방법으로는 수정할 기회가 없을 수도 있지 않을까요?

그것이 바로 문제였습니다!내 스케줄러에서 너무 빨리 호출되어 다른 어떤 것도 '작업'에 액세스할 수 없었습니다.도움을 주셔서 감사합니다!

도움이 되었습니까?

해결책

뭔가 작업이 잠겨 있습니다.어떤 종류의 애플리케이션인지에 따라 시스템의 전체 스택 덤프를 얻을 수 있지만 방법은 다양합니다.예를 들어 대부분의 Windows 기반 앱 서버에서 CTRL-Break를 사용하면 이 작업을 수행할 수 있고 Linux에서 SIGQUIT를 보내면 동일한 작업을 수행할 수 있을 것으로 생각합니다.

스택 덤프를 얻은 후에는 이를 통해 해당 개체에 대한 잠금이 있는 다른 스레드를 찾아볼 수 있습니다.

당신은 또한 사용할 수 있습니다 VisualVM 동일한 최종 목표에 대해 스택 덤프를 얻으려면 다음을 수행하십시오.

로컬 애플리케이션이 실행되는 동안 Java VisualVM을 사용하여 스레드 덤프 (스택 추적)를 가져갈 수 있습니다.스레드 덤프를 복용한다고해서 응용 프로그램이 중지되지 않습니다.스레드 덤프를 인쇄하면 Java 스레드의 스레드 상태가 포함 된 스레드 스택의 인쇄물이 나타납니다.

Java VisualVM에서 스레드 덤프를 인쇄하면 도구는 응용 프로그램의 활성 스레드의 스택 추적을 인쇄합니다.Application에 대한 명령 줄 콘솔이없는 경우 Java VisualVM을 사용하여 스레드 덤프를 사용하는 것이 매우 편리 할 수 ​​있습니다.스택 추적을 사용하여 교착 상태와 같은 여러 가지 문제를 진단하거나 응용 프로그램이 중단 될 때.

다른 팁

다른 스레드가 동기화 잠금을 유지할 수 있습니까? tasks?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top