2014-06-12 4 views
2

다음 코드가 있습니다.스레드에서 메소드 호출이 완료되지 않음 - 스레드 종료 방법 - 해결 방법

ReadWriteLock someLock = new ReentrantReadWriteLock(); 
Condition someCondition = someLock.writeLock().newCondition(); 

public someMethod() { 
    // do some stuff 
    someCondition.await(); //Lock here. 
    System.out.prinltn("This never prints"); 
} 

public doSomeStuff() { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      try { 
       someMethod(); 
       System.out.println("thread finished"); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("thread is going to die"); 
     } 
    }).start(); 
} 

스레드가 메서드 someMethod()을 호출하면 실행됩니다. 그러나 그 기능에 대해 await() 방법이 있기 때문에. 그것은 결코 끝나지 않습니다/singnalAll()에 의해 깨우지 않는 한 'This never prints'를 인쇄하지 않습니다. 하지만 스레드가 실행되면 끝내기를 원합니다.

저는 모든 것을 리펙토링 할 수 없습니다. 이 문제에 대한 해결 방법이 필요합니다. 스윙 응용 프로그램에 사용됩니다. 그래서 스레드가 중요합니다.

Thread thread = 
    new Thread(new Runnable() { 
    @Override 
    public void run() { 
     try { 
      someMethod(); 
      System.out.println("thread finished"); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("thread is going to die"); 
    } 
    }); 

thread.start(); 

final long reasonableTimeout = ...; 

thread.join(reasonableTimeout); 

// THIS WILL SHAKE IT UP 
thread.interrupt(); 

thread.join(); 

// At this point, it is guaranteed that the thread has finished 
+1

메서드 호출에 관련 스레드가 있어야합니다. 현재 스레드를 풀어 끝내기를 원한다면 다른 스레드를 만들고 그 스레드에서 메서드를 호출해야합니다. –

+0

@JigarJoshi는 정교하게 처리합니까? –

+0

업데이트 (조심 :)) –

답변

2

나는이 할 것, 생각() 끝내기 위해. 즉, 실행 흐름을 기본적으로 두 개로 분기하는 것을 의미합니다. someMethod()는 적절한 각성을 기다리고 있고, 다른 일부는 호출자가 계속 진행하는 곳입니다. someMethod를 호출 한 후 완료해야합니다.(). 이렇게하려면 someMethod()를 별도의 스레드에서 실행해야합니다. 이 같은.

public doSomeStuff() { 
    new Thread(new Runnable() { 
     @Override 
     public void run() { 
     try { 
      new Thread(){ 
       public void run(){ 
        someMethod(); 
       } 
      }.start(); 
      System.out.println("thread finished"); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.out.println("thread is going to die"); 
    } 
    }).start(); 
} 
+0

흠! :-) 당신이 생각할 수있는 깨끗한 해결 방법은 무엇입니까? –

+0

@Kevin 귀하의 요구 사항은 깨끗하지 않으므로 매우 깨끗합니다. 필자는 개인적으로'someMethod'를 재 작성하지만 써드 파티 라이브러리의 일부라면 선택하지 않을 수도 있습니다. –

1

내가 제대로 질문을 이해 확실하지 오전하지만 난 당신이 것으로 someMethod() 함수를 시작한 다음 것으로 someMethod을 기다리지 않고 발신자 출구를 만들고 싶어 생각 :

+0

사이트 밖에서, 마음이 멀어 졌습니까? 이제는 하나의 스레드 대신에 두 개가 있고 문제가 남아 있습니다. –

1

두 가지 방법으로 해결할 수 있습니다.

1)

이 방어 코딩을 수행 중단 정책으로 작업을 디자인합니다. 어떤 방법 으로든 당신의 업무가 중단된다면, 프로그램은 그것을 다루는 방법을 알아야합니다.

2) 당 자바 동시성과 같이

public someMethod() { 
    while(condition predicate){ 
    someCondition.await(TIME_OUT); //Lock here. 
} 
//ADD Poison pill here 
    System.out.prinltn("This never prints"); 
}  

일단

조건 대기 (가 Object.wait 또는 조건을 사용하여 연습,이 example으로하는 극약 처방을 추가합니다. await) :

1) 항상 조건부 조건부 테스트를 통해 개체의 상태를 테스트합니다. 진행하기 전에 진행해야합니다.

2) wait를 호출하기 전에 항상 조건 술어를 테스트하고 wait에서 리턴 한 후 다시 테스트하십시오.

3) 항상 루프에서 대기를 호출하십시오.

4) 조건 술어를 구성하는 상태 변수가 상태 큐와 연관된 잠금 에 의해 보호되는지 확인하십시오.

5) wait, notify 또는 notifyAll을 호출 할 때 조건 큐와 관련된 잠금을 유지하십시오.

6) 조건 술어를 확인한 후 작동하기 전에 잠금을 해제하지 마십시오.

관련 문제