스레드 시작 :
1. start ()와 run ()의 차이에 대한 설명
start () : 함수는 새 스레드를 시작하는 것이며 새 스레드는 해당 run () 메소드를 실행합니다. start ()는 반복적으로 호출 할 수 없습니다.
run () : run ()은 일반 멤버 메소드처럼 반복적으로 호출 할 수 있습니다. run ()을 별도로 호출하면 현재 스레드에서 run ()가 실행되며 새 스레드가 시작되지 않습니다!
다음은 설명 할 코드입니다.
클래스 신화는 스레드 {public void run () {...}}; Mythread Mythread = new Mythread (); Mythread.start ()는 새 스레드를 시작하고 새 스레드에서 run () 메소드를 실행합니다.
mythread.run ()은 현재 스레드에서 run () 메소드를 직접 실행하며 run ()을 실행하기 위해 새 스레드를 시작하지 않습니다.
2. start ()와 run ()의 차이의 예
아래에서 간단한 예제로 그들 사이의 차이점을 보여줍니다. 소스 코드는 다음과 같습니다.
// demo.java의 소스 코드 클래스 Mythread는 스레드 {public mythread (문자열 이름) {super (name); } public void run () {system.out.println (thread.currentThread (). getName ()+"is running"); }. System.out.println (thread.currentthread (). getName ()+"Call Mythread.run ()"); mythread.run (); System.out.println (thread.currentThread (). getName ()+"Call Mythread.start ()"); mythread.start (); }} 실행 결과 :
Main Call Mythread.run () 메인은 RunningMain ice rund mythread.start () mythread가 실행 중입니다
결과 설명 :
(1) thread.currentthread (). getName ()은 "현재 스레드"의 이름을 얻는 데 사용됩니다. 현재 스레드는 CPU에서 실행될 예정인 스레드를 나타냅니다.
(2) Mythread.run ()은 "Main Thread Main"에서 호출되고 run () 메소드는 "Main Thread Main"에서 직접 실행됩니다.
(3) Mythread.start ()는 "Thread Mythread"를 시작합니다. "스레드 Mythread"가 시작되면 run () 메소드가 호출됩니다. 이 시점에서 run () 메소드는 "스레드 Mythread"에서 실행됩니다.
스레드 인터럽트 및 종료
1. 스레드 인터럽트 : 인터럽트 ()
인터럽트 ()의 함수는 스레드를 방해하는 것입니다.
이 스레드는 자체를 방해 할 수 있습니다. 다른 스레드 가이 스레드의 인터럽트 () 메소드를 호출하면 CheckAccess ()를 통해 권한이 확인됩니다. 보안 예외 예외가 발생할 수 있습니다.
스레드가 차단 상태에있는 경우 : 대기 (), 대기 (long) 또는 대기 (long, int)가 대기 (차단) 상태로 만들거나 join (), 조인 (long, int), sleep (long, int)도 차단 상태로 만듭니다. 스레드가 차단 될 때 인터럽트 () 메소드를 호출하면 "인터럽트 상태"가 지워지고 InterruptedException이 수신됩니다. 예를 들어, 스레드는 Wait ()를 통해 차단 상태로 들어가고 스레드는 interprupt ()에 의해 중단됩니다. 인터럽트 () 호출은 즉시 스레드의 인터럽트 플래그를 "true"로 설정하지만 스레드가 차단 상태에 있으므로 "인터럽트 플래그"가 즉시 "false"로 지워지고 InterpruptedException이 생성됩니다.
스레드가 선택기 선택기에서 차단되면 인터럽트 ()에 의해 중단 될 때; 스레드의 인터럽트 플래그가 True로 설정되어 선택 작업에서 즉시 반환됩니다.
위에서 언급 한 상황에 속하지 않으면 스레드가 인터럽트 ()을 통해 중단되면 인터럽트 플래그가 "true"로 설정됩니다.
"종료 된 스레드"를 방해해도 작업이 발생하지 않습니다.
2. 스레드 종료
스레드의 STOP () 및 SPERNEND () 메소드는 고유 한 불안으로 인해 사용하지 않는 것이 좋습니다!
다음으로 먼저 "차단 상태"및 "실행 상태"에서 스레드의 종료 방법에 대해 논의한 다음 일반적인 방법을 요약합니다.
1. "차단 상태"에서 실을 종료합니다.
일반적으로 "인터럽트"에 의해 "차단 상태"에서 스레드를 종료합니다.
Sleep (), Wait (), join () 및 기타 방법으로 인해 스레드가 차단 상태로 들어가면; 현재 스레드의 인터럽트 ()가 호출되면 스레드의 인터럽트 마크가 true로 설정됩니다. 차단 상태에 있으므로 인터럽트 플래그가 지워지고 인터럽트 예외 예외가 생성됩니다. 적절할 때까지 InterruptedException을 넣는 것은 다음과 같이 형식으로 스레드를 종료 할 수 있습니다.
@OverRidePublic void run () {try {while (true) {// 작업 실행 ...}} catch (InterpruptedException) {// InterruptedException Exception, Exit the the (true) 루프와 스레드가 종료됩니다! }} 참고 : 작업이 계속 (true)에서 지속적으로 실행되면 스레드가 차단 상태에있을 때 스레드의 인터럽트 () 호출은 인터럽트 한 외환 인터럽트를 생성합니다. 중단 된 캡처는 외부 (true) 외부에 있으므로 while (true) 루프를 종료합니다!
참고 : InterruptedException의 캡처는 일반적으로 while (true) 루프 본체 외부에 배치되므로 예외가 생성 될 때 while (true) 루프가 종료되도록합니다. 그렇지 않으면, InterruptedException이 가중 (True) 루프 본체 내에있는 경우 추가 추가 및 종료 처리가 필요합니다. 양식은 다음과 같습니다.
@overridepublic void run () {while (true) {try {// execute task ...} catch (InterpruptedException) {// InterruptedException은 (true) 루프 본체입니다. // 스레드가 InterruptedException 예외를 생성 할 때 (true)는 계속 실행할 수 있습니다! 휴식을 수동으로 종료해야합니다. }}} 참고 : 위의 인터럽트 예외 예외는 WHLE (true) 내에서 포착됩니다. InterruptedException 예외가 생성되면 Catch에 의해 처리되지 않으며 여전히 (True) 루프 본체입니다. wough (true) 루프 바디를 종료하려면 exiting the the the the the the the the the the the the the the the the the the the the the experts를 수행해야합니다.
2. "실행 상태"에서 스레드를 종료합니다.
일반적으로 "마킹"으로 "실행 상태"에서 스레드를 종료합니다. 그중에는 "인터럽트 플래그"와 "추가 플래그 추가"가 포함됩니다.
(1) "인터럽트 플래그"를 통해 스레드를 종료합니다.
양식은 다음과 같습니다.
@overridepublic void run () {while (! islerrupted ()) {// execute task ...}} 설명 : istrictrupted ()는 스레드의 인터럽트 플래그가 참인지 결정합니다. 스레드가 실행 중이며 우리는 그것을 종료해야합니다. 스레드의 인터럽트 () 메소드를 호출 할 수 있고 스레드의 인터럽트 플래그가 적용됩니다. 이 시점에서 while 루프가 종료됩니다.
참고 : 인터럽트 ()는 "실행 상태"에서 스레드를 종료하지 않습니다! 스레드의 인터럽트 플래그를 true로 설정합니다.
(2) "추가 자국 추가"를 통과합니다.
양식은 다음과 같습니다.
개인 휘발성 부울 플래그 = true; 보호 된 void stoptask () {flag = false;}@atriadepublic void run () {while (flag) {// execute task ...}} 설명 : 스레드에 플래그 태그가 있으며 기본값은 참입니다. 그리고 우리는 플래그 태그를 설정하기 위해 stoptask ()를 제공합니다. 스레드를 종료해야 할 때 스레드의 stoptask () 메소드를 호출하면 스레드가 while 루프를 종료 할 수 있습니다.
참고 : 플래그는 플래그의 가시성을 보장하기 위해 휘발성 유형으로 정의됩니다. 즉, 다른 스레드가 stoptask ()를 통해 플래그를 수정 한 후이 스레드는 수정 된 플래그 값을 볼 수 있습니다.
"차단 상태"및 "실행 상태"에서 스레드의 종료 방법을 포괄적으로, 더 일반적인 종료 스레드는 다음과 같습니다.
@overridepublic void run () {try {// 1. istinerrupted ()는 인터럽트가 사실이 표시되는 한 스레드가 종료되도록 보장합니다. while (! istrupted ()) {// execute task ...}} catch (InterpruptedException) {// 2. InterpruptedException 예외는 인터럽트 예외 예외가 발생하면 스레드가 종료되도록 보장합니다. }} 3. 스레드 종단의 예
인터럽트 ()는 종종 "차단 상태"스레드를 종료하는 데 사용됩니다. 다음 예를 참조하십시오.
// demo1.java의 소스 코드 클래스 Mythread는 스레드 {public mythread (문자열 이름) {super (name); } @override public void run () {try {int i = 0; while (! islerrupted ()) {thread.sleep (100); // Sleep 100ms I ++; System.out.println (thread.currentthread (). getName ()+"("+this.getSte ()+") loop"+i); }} catch (InterpruptedException e) {System.out.println (thread.currentThread (). getName ()+"("+this.getState ()+") CATCHURPTEDEXCEPTION"); }}} public class demo1 {public static void main (String [] args) {try {Thread T1 = new Mythread ( "T1"); // 새 "스레드 t1"system.out.println을 만듭니다 (t1.getName ()+"("+t1.getState ()+")가 새로 새로워집니다."); t1.start (); // "스레드 t1"system.out.println (t1.getName ()+"("+t1.getState ()+")가 시작되었습니다."); // 메인 스레드는 300ms에 잠을 자고 주 스레드는 "인터럽트"명령을 T1로 보냅니다. Thread.sleep (300); t1.interrupt (); System.out.println (t1.getName ()+"("+t1.getState ()+")가 중단되었습니다."); // 메인 스레드는 300ms를 위해 자고 T1의 상태를 확인합니다. Thread.sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+")가 지금 중단되었습니다."); } catch (InterruptedException e) {e.printstacktrace (); }}} 실행 결과 :
T1 (new)는 new.t1 (runnable)이 시작되었습니다 .T1 (runnable) loop 1T1 (runnable) 루프 2T1 (timed_waiting)이 중단되었습니다 .T1 (runnable) CATCHINGEDEXCEPTION.T1 (종료)이 중단되었습니다.
결과 설명 :
(1) 메인 스레드 메인은 New Mythread ( "T1")를 통해 스레드 T1을 생성 한 다음 스레드 T1 ~ T1.start ()를 시작합니다.
(2) T1이 시작된 후 인터럽트 플래그가 지속적으로 점검됩니다. 인터럽트 플래그가 "false"인 경우 100ms에 잠을 자게됩니다.
(3) T1이 잠을 자면 메인 스레드 메인으로 전환됩니다. 기본 스레드가 다시 실행되면 T1.interrupt ()가 실행되어 스레드 T1을 방해합니다. T1이 인터럽트 명령을 수신 한 후, T1의 인터럽트 플래그는 "False"로 설정되고 InterruptedException이 발생됩니다. T1의 Run () 방법에서는 루프 본체 밖에서 잡힌 예외입니다. 따라서 루프가 종료됩니다.
위의 결과를 작은 수정하고 run () 메소드의 InterruptedException 예외를 while 루프 본체로 옮긴 코드 블록을 이동했습니다.
// demo2.java의 소스 코드 클래스 Mythread는 스레드 {public mythread (문자열 이름) {super (name); } @override public void run () {int i = 0; while (! isTerrupted ()) {try {thread.sleep (100); // 100ms for 100ms} catch (InterpruptedException) {System.out.println (thread.currentThread (). getName ()+"("+this.getState ()+") CATCHUBEDEXCEPTION"); } i ++; System.out.println (thread.currentthread (). getName ()+"("+this.getSte ()+") loop"+i); }}} public class demo2 {public static void main (String [] args) {try {Thread T1 = new Mythread ( "T1"); // 새 "스레드 t1"system.out.println을 만듭니다 (t1.getName ()+"("+t1.getState ()+")가 새로 새로워집니다."); t1.start (); // "스레드 t1"system.out.println (t1.getName ()+"("+t1.getState ()+")가 시작되었습니다."); // 메인 스레드는 300ms에 잠을 자고 주 스레드는 "인터럽트"명령을 T1로 보냅니다. Thread.sleep (300); t1.interrupt (); System.out.println (t1.getName ()+"("+t1.getState ()+")가 중단되었습니다."); // 메인 스레드는 300ms를 위해 자고 T1의 상태를 확인합니다. Thread.sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+")가 지금 중단되었습니다."); } catch (InterruptedException e) {e.printstacktrace (); }}} 실행 결과 :
T1 (new)는 new.t1 (runnable)이 시작되었습니다 .T1 (runnable) loop 1T1 (runnable) 루프 2T1 (timed_waiting) t1 (runnable) CATCHINTEDEXCEPTION.T1 (RUNNABLE) LOOP 3T1 (RUNNABLE) LOOP 4T1 (RUNNABLE) LOOP 5T1 (timed_waiting)의 중첩. (Runnable) 루프 6T1 (Runnable) 루프 7T1 (Runnable) LOOP 8T1 (Runnable) LOOP 9 ...
결과 설명 :
이 프로그램은 죽은 루프에 들어갔다!
왜 이런 일이 일어나고 있습니까? T1이 "대기 (차단) 상태"에있을 때 T1이 인터럽트 ()에 의해 중단되기 때문입니다. 이 시점에서 인터럽트 플래그가 지워지고 [Interrupted ()가 거짓을 반환합니다. 따라서 T1은 자연스럽게 악순환에 들어갑니다.
이 문제를 해결하려면 예외를 포착 할 때 while 루프를 종료하려면 추가 처리가 필요합니다. 예를 들어, 신화 캐치 (InterruptedException)에 브레이크 또는 복귀를 추가하면 문제가 해결 될 수 있습니다.
다음은 "추가 태그 추가"로 "상태 상태"를 종료하는 스레드의 예입니다.
// demo3.java의 소스 코드 클래스 Mythread는 스레드를 확장합니다. public void stoptask () {flag = false; } public mythread (문자열 이름) {super (name); } @override public void run () {synchronized (this) {try {int i = 0; while (flag) {thread.sleep (100); // Sleep 100ms I ++; System.out.println (thread.currentthread (). getName ()+"("+this.getSte ()+") loop"+i); }} catch (InterpruptedException IE) {System.out.println (Thread.CurrentThread (). getName ()+"("+this.getState ()+") CATCHURPTEDException."); }}}} public class demo3 {public static void main (String [] args) {try {mythread t1 = new Mythread ( "T1"); // 새 "스레드 t1"system.out.println (t1.getName ())+"("+t1.getState ()+")가 새로 새로워집니다."); t1.start (); // "스레드 t1"system.out.println (t1.getName ()+"("+t1.getState ()+")가 시작되었습니다."); // 메인 스레드는 300ms에 잠을 자고 주 스레드는 "인터럽트"명령을 T1로 보냅니다. Thread.sleep (300); t1.stoptask (); System.out.println (t1.getName ()+"("+t1.getState ()+")가 중단되었습니다."); // 메인 스레드는 300ms를 위해 자고 T1의 상태를 확인합니다. Thread.sleep (300); System.out.println (t1.getName ()+"("+t1.getState ()+")가 지금 중단되었습니다."); } catch (InterruptedException e) {e.printstacktrace (); }}} 실행 결과 :
T1 (new)는 new.t1 (runnable)이 시작되었습니다 .T1 (runnable) loop 1T1 (runnable) 루프 2T1 (TIMED_WAITING)이 중단되었습니다 .T1 (runnable) 루프 3T1 (종료)이 중단되었습니다.