2017-01-17 2 views
5

내 스레드를 중지 할 수 없습니다 ???스레드를 중지 할 수 없습니다

class Threadz { 

    class runP implements Runnable { 
     int num; 
     private volatile boolean exit = false; 
     Thread t; 
     public runP() { 
      t = new Thread(this, "T1"); 
      t.start(); 
     } 

     @Override 
     public void run() { 
      while(!exit) { 
       System.out.println(t.currentThread().getName()+": "+num); 
       num++; 
       try { 
        t.sleep(200); 
       } catch(InterruptedException e) {} 
      } 
     } 
     public void stop() { 
      exit = true; 
     } 
    } 

    public static void main(String[] a) { 
     runP rp = new Threadz().new runP(); 
     if(rp.num == 1) {rp.stop();} 
    } 

} 

rp.num == 0을 사용하면 스레드를 즉시 중지 할 수 있습니다. 하지만, 왜 rp.num == x (x는 0보다 큰 숫자)를 변경하면 스레드가 멈출 수 없습니까? 이 일을 해결하도록 도와주세요 ... 도움을 주셔서 감사합니다.

+2

같아요'runP의 RP처럼 보일 것이다 = new Threadz(). 새로운 runP();'가 스레드를 만들고 시작합니다. 그러나 다른 스레드가 실제로 실행되기 직전에 _might_가 실행되기 바로 직전에'if (rp.num == 1) {rp.stop();}'num이 여전히 0이되도록 스레드가 이미 가질 수 있습니다. 'rp.num == 1 '을 검사하는 것이 너무나 힘들고 아마도 실패 할 확률이 훨씬 더 높습니다. – Thomas

+0

'rp.num == 1'대신'rp.num> 1 '을 사용하여 실수로 중지 조건을 건너 뛰지 않도록 스레드를 중지하십시오. – Quota

+0

이 접근법을 실제로 유지하려면 AtomicBoolean을 사용해야합니다. 또한 ==를 두 번 치는 사이에 시간표가 필요합니다. 당신은 더 나은> – efekctive

답변

3

이 코드가 스레드의 run() 메소드에서 실행되지 않기 때문에 :

runP rp = new Threadz().new runP(); 
    if (rp.num == 1) { 
     rp.stop(); 
    } 

INT의 기본 값은 0 입니다하지만 반드시 모든 사형 집행 사실이 아니다 그것은 0으로 작동

: if (rp.num == 0)

가 runP 스레드의 실행 방법에 정지 상태를 이동

: 실행하고 확인 전에 num를 증가 할 수 runP의 thread와 응용 프로그램의

+0

괜찮아 .. 내가 할 수있는 모든 방법을 시도했지만이 선택의 여지가 ... 고마워 형편 – BeginnerToJava

+0

내가 2 스레드, 1 스레드에서 다른 스레드로 var를 전달하는 방법? 어떻게 말해 줄 수 있니? – BeginnerToJava

+0

환영합니다 :) 변수를 전달할 필요없이 스레드간에 공유 할 필요가 없습니다. runP 스레드간에 공유하는 AtomicInteger를 사용하고 RunP 생성자에서 AtomicInteger를 제공 할 수 있습니다. 그것은 좋을 것입니다. – davidxxx

0

프로그램을 여러 번 실행하면 프로그램이 실제로 중단 될 수 있습니다.

이유는 값을 변경하여 run() 방법에 num++ 전에

if(rp.num == 1) {rp.stop();} 

을 실행 훨씬 더 가능성이 프로그램을 실행할 때입니다.

그러나 우연히 main 메서드에서 if 문 앞에 run 메서드의 루프가 실행되는 경우가있을 수 있습니다.

예 : 지속적으로 상태를 확인하기 위해이 일이 있는지 확인하기 위해

하나의 방법

public static void main(String[] a) { 
    runP rp = new Threadz().new runP(); 

    while(true){ 
     if(rp.num == 1) { 
     rp.stop(); 
     break; 
     } 
    } 
} 
0

스레드가 run 메소드 실행을 시작하기 전에 아래의 명령문이 실행 중입니다.

if(rp.num == 1) {rp.stop();} 

위의 문 앞에 Thread.sleep을 추가하면 루프를 시작한 후에이 문을 실행할 것이므로 올바르게 작동합니다.

public static void main(String[] a) { 
    runP rp = new Threadz().new runP(); 
    try { 
     Thread.sleep(2000); 
    } catch (InterruptedException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    if(rp.num > 1) {rp.stop();} 
} 

나는 그것을 테스트하기 위해 1 이상 만들었습니다.

0

rp.num == 1을 확인하는 것은 rp.num이 정확히 하나 인 지점에서 정확히 발생해야합니다. 다소 어려울 수 있습니다.

main 메서드에서 num을 200ms마다 증가시키는 스레드를 시작합니다. 그 다음에 num == 1이 있는지 확인하지만 정확히이 코드가 실행될 때 실제로 제어 할 수없는 요소 (예 : OS ... 등)에 따라 달라집니다. 이것은 10ms 후 (값이 1 일 때) 일 수 있지만 300ms 이후 일 수도 있습니다 (값이 이미 2 일 때). 또한 스레드가 정확하게 시작될 때 확실하지 않습니다. 따라서 테스트 후에 만 ​​스레드가 시작될 수도 있습니다. if(rp.num == 1) {rp.stop()}; 수표를 간단한 인쇄 명세서 System.out.println(rp.num)으로 바꾸면 쉽게 테스트 할 수 있습니다. 인쇄하기 전에 추가 시간을 기다리면 내가 말하는 것에 대해 더 잘 알게 될 것입니다.

당신이 외부에서 실행 가능한을 중지하고 싶은 가정하면, 나는 Observer pattern 같은 것을 사용하는 것이 좋습니다 :

class MyRunnable implements Runnable { 

    private final MyListener l; 
    private volatile boolean exit; 
    int num; 

    public MyRunnable(MyListener l) { 
     this.l = l; 
     exit = false; 
    } 

    @Override 
    public void run() { 
     while(!exit) { 
      System.out.println(t.currentThread().getName()+": "+num); 
      l.check(num++); 
      try { 
       t.sleep(200); 
      } catch(InterruptedException e) {} 
     } 
    } 

    public void stop() { 
     exit = true; 
    } 
} 

class MyListener { 

    private final threshold; 

    public MyListener(int x) { 
     this.threshold = x; 
    } 

    public void check(MyRunnable r, int num) { 
     if (num >= threshold) 
      r.stop(); 
    } 

} 

및 주요 방법은

public static void main(String[] args) { 
    MyListener l = new MyListener(1); 
    Runnable r = new MyRunnable(l); 
    new Thread(r).start(); 
} 
관련 문제