스 레 드 의 정확 한 정지

스 레 드 가 멈 추 는 몇 가지 방법:
  • 스 레 드 운행 완료,정상 정지
  • 4.567917.stop 방법 을 집행 하고 폭력 이 정지 되 었 으 며 현재 버 려 졌 다.
    4.567917.interrupt 방법 을 실행 하고 지금 사용 합 니 다
    stop 방법 은 왜 버 려 졌 습 니까?
    stop 방법 으로 스 레 드 를 종료 하면 이 스 레 드 가 잠 겨 있 는 모든 모니터 를 방출 합 니 다.스 레 드 가 잠 겨 있 는 대상 의 내용 을 수정 하면 정상적으로 처리 되 기 전에 스 레 드 가 종 료 됩 니 다.데이터 가 일치 하지 않 는 결 과 를 초래 할 것 이다.
    예 를 들 어 은행 에서 돈 을 인출 하 는 예:온라인 과정 A 에서 인출 작업 을 하 는데 인출 작업 은 동기 화 방법 이다.그 중에서 모두 세 가지 절차 가 있다.비밀 번 호 를 입력 하고 돈 을 찾 으 며 잔액 을 수정 하 는 것 이다.사용자 a 가 비밀 번 호 를 입력 하고 돈 을 찾 은 후에 스 레 드 A.stop();스 레 드 종료.수 정 된 잔액 이 아직 데이터 베 이 스 를 다시 쓰 지 않 아 데이터 가 혼 란 스 러 웠 다.
    예 를 들 어 설명:먼저 작업 클래스 Login 을 정의 합 니 다.
    package com.feng.example;
    
    public class Login {
    	private String username="a";
    	private String password="aa";
    	
    	
    	synchronized public String getUsername() {
    		return username;
    	}
    	
    	public void setUsername(String username) { 
    		this.username = username;
    	}
    	
    	synchronized public String getPassword() {
    		return password;
    	}
    	
    	public void setPassword(String password) {
    		this.password = password;
    	}
    	
    	synchronized public void login(String username, String passwd)
    	{
    		this.username = username;
    		try {
    			Thread.sleep(20000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		this.password = passwd;
    	}
    	
    
    }

    스 레 드 클래스 정의,login 방법 호출
    package com.feng.example;
    
    public class LoginThread extends Thread{
    
    	private Login login;
    	
    	public LoginThread(Login login)
    	{
    		this.login = login;
    	}
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		super.run();
    		login.login("b", "bb");
    		
    	}
    
    }

    테스트 클래스:
    package com.feng.example;
    
    public class LoginTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Login login = new Login();
    		Thread thread = new LoginThread(login);
    		thread.start();
    		try {
    			Thread.sleep(2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		thread.stop();  //      
    		
    		System.out.println(login.getUsername()+"========"+login.getPassword());
    		
    
    	}
    
    }

    분석:login 대상 의 username 초기 값 은 a 이 고 password 초기 값 은 aa 이 며 스 레 드 thread 는 login("b","bb")을 호출 합 니 다.방법,username 의 값 을 b 로 변경 합 니 다.이 때 스 레 드 는 20 초 동안 휴면 하고 스 레 드 thread start 후 2 초 동안 thread.stop 을 호출 하여 스 레 드 가 종 료 됩 니 다.login 대상 에 대한 자 물 쇠 를 풀 어 줍 니 다.login 에 대한 자 물 쇠 를 풀 어야 동기 화 방법 getUsername 과 getPassword 를 호출 할 수 있 습 니 다.
    프로그램 실행 결과:
    b========aa

    올 바른 스 레 드 정지 방식
    interrupt 방법 을 사용 합 니 다.이 방법 은 스 레 드 에 표 시 를 할 뿐 이 스 레 드 가 종 료 될 것 임 을 표시 합 니 다.(하나의 태그 일 뿐 스 레 드 를 종료 하 는 행 위 를 하지 않 았 습 니 다)interrupted 방법 이나 isInterrupted 방법 에 맞 춰 스 레 드 가 멈 출 지 여 부 를 검사 합 니 다.해당 작업 을 마 친 후 break 또는 return 을 사용 하여 정상적으로 실행 되 거나(순환 체 가 있 는 경우)이상 을 던 지 는 방식 으로 스 레 드 를 종료 합 니 다(추천 합 니 다)
    상기 내용 을 통 해 알 수 있 듯 이 스 레 드 를 정확하게 정지 하 는 사상 은 바로 특정한 수단 으로 스 레 드 를 정상적으로 정지 시 키 거나 이상 한 방식 으로 스 레 드 를 중지 하 는 것 이다.
    1.interrupted 와 isInterrupted 방법 소개
    interrupted 방법 정적 방법 현재 스 레 드(이 방법 을 실행 하 는 스 레 드)가 중단 되 었 는 지 확인 합 니 다(중단 표시 가 있 는 지 판단 합 니 다)
    isInterrupted 방법 호출 자가 중단 되 었 는 지 검사 합 니 다.
    interrupted 방법의 사용 을 테스트 하고 MyThread 스 레 드 클래스 를 만 듭 니 다.
    package com.feng.example;
    
    public class MyThread extends Thread {
    	
    	@Override
    	public void run() {
    		int i = 0;
    		while(true)
    		{
    			i++;
    		}
    
    	}	
    }

    테스트 클래스:
    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Thread thread = new MyThread();
    		thread.start();
    		thread.interrupt();
    		System.out.println(thread.interrupted()+"=========="+Thread.interrupted()); //main         ,       main
    		System.out.println(thread.interrupted()+"=========="+Thread.interrupted());
    		
    	}
    
    }

    분석:main 함수 에서 thread 를 시작 한 다음 thread.interrupt()를 사용 하여 스 레 드 를 종료 합 니 다.(사실은 종료 표 시 를 하 는 것 입 니 다)출력 문 에 서 는 interrupted 방법 을 사용 합 니 다.이 방법 은 현재 스 레 드 를 검 측 했 습 니 다.즉,이 말 을 실행 하 는 스 레 드 는 main 입 니 다.main 이 아 닌 thread 를 종료 하기 때문에 인쇄 된 결 과 는 모두 false 입 니 다.
    interrupted 는 정적 방법 이기 때문에 thread.interrupted()를 사용 하 는 것 은 Thread.interrupted()와 같 습 니 다.
    테스트 결과:
    false==========false
    false==========false

    위의 테스트 프로그램 을 수정 하여 메 인 스 레 드 를 종료 시 킵 니 다.수정 프로그램 은 다음 과 같 습 니 다.
    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Thread thread = new MyThread();
    		thread.start();
    		Thread.currentThread().interrupt();
    		System.out.println(thread.interrupted()+"=========="+Thread.interrupted()); //main         ,       main
    		System.out.println(thread.interrupted()+"=========="+Thread.interrupted());
    		
    	}
    
    }

    분석:현재 종 료 된 것 은 메 인 스 레 드 이 므 로 출력 할 때 thread.interrupted()출력 true 를 호출 합 니 다.interrupted 방법 은 중단 표 시 를 제거 하 는 기능 이 있 기 때문에 interrupted()방법 을 다시 호출 할 때 false 를 출력 합 니 다.
    테스트 는 다음 과 같 습 니 다:
    true==========false
    false==========false

    테스트 프로그램 을 수정 하여 isInterrupted 방법 을 보 려 면:
    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Thread thread = new MyThread();
    		thread.start();
    		thread.interrupt();
    		System.out.println(thread.isInterrupted()+"=========="+thread.isInterrupted()); //main         ,       main
    		
    	}
    
    }

    분석:isInterrupted 방법 은 중단 표 시 를 제거 하 는 역할 을 하지 않 기 때문에 두 번 의 출력 은 모두 true 입 니 다.
    실행 결과:
    true==========true

    2.break 를 사용 하여 순환 을 뛰 어 내 리 는 것 은 스 레 드 가 실 행 된 것 입 니 다.
    스 레 드 클래스 수정
    package com.feng.example;
    
    public class MyThread extends Thread {
    	
    	@Override
    	public void run() {
    		int i = 0;
    		while(true)
    		{
    			if(this.interrupted())  //    this.isInterrupted()   
    			{
    				//      
    				System.out.println("      ");
    				break;
    			}
    			i++;
    		}
    
    	}	
    }

    테스트 클래스 코드:
    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Thread thread = new MyThread();
    		thread.start();
    		thread.interrupt();
    		
    	}
    
    }

    while(true)순환 에서 중단 되면 순환 에서 벗 어 나 는 것 을 판단 하면 thread.interrupt()도 볼 수 있 습 니 다.단지 인 터 럽 트 표 시 를 할 뿐이다.라인 이 이 인 터 럽 트 표 시 를 감지 한 후에 필요 한 조작 을 한 후에 순환 을 해서 정상적으로 라인 을 실행 할 수 있다.
    실행 결과:
          

    3.return 을 사용 하여 스 레 드 종료
    만약 에 상기 스 레 드 에 여러 개의 순환 이 있다 면 break 는 하나의 순환 만 뛰 어 내 려 다른 순환 에 들 어 갈 수 있 고 스 레 드 를 중지 할 수 없습니다.우 리 는 return 을 사용 하여 순환 을 종료 할 수 있 습 니 다.
    먼저 문제 보기:상기 스 레 드 류 수정
    package com.feng.example;
    
    public class MyThread extends Thread {
    	
    	@Override
    	public void run() {
    		
    		for(int i=0; i<1000; i++)
    		{
    			if(this.isInterrupted())
    			{
    				//      
    				System.out.println("      ");
    				break;
    			}
    			i++;
    		}
    		
    		System.out.println("       ,                ");
    
    	}	
    }

    실행 결과 보기:

    break 를 사용 하면 순환 밖의 문 구 는 실 행 됩 니 다.순환 밖의 문 구 를 실행 하지 않 으 려 면 return 으로 바 꿉 니 다.
    스 레 드 클래스 코드 수정:
    package com.feng.example;
    
    public class MyThread extends Thread {
    	
    	@Override
    	public void run() {
    		
    		for(int i=0; i<1000; i++)
    		{
    			if(this.isInterrupted())
    			{
    				//      
    				System.out.println("      ");
    				return;
    			}
    			i++;
    		}
    		
    		System.out.println("       ,                ");
    
    	}	
    }

    실행 결 과 는 다음 과 같 습 니 다.
          

    return 은 일반적으로 코드 에 오염 을 일 으 킬 수 있 기 때문에 우 리 는 이상 한 방법 을 던 져 서 스 레 드 를 중지 하 는 것 을 권장 합 니 다.
    4.이상 던 지기,스 레 드 종료
    스 레 드 클래스 수정
    package com.feng.example;
    
    public class MyThread extends Thread {
    
    	@Override
    	public void run() {
    
    		try {
    			for (int i = 0; i < 1000; i++) {
    				if (this.isInterrupted()) {
    					//       
    					System.out.println("      ");
    					throw new InterruptedException();
    				}
    				i++;
    			}
    			
    			System.out.println("       ,                ");
    			
    		} catch (InterruptedException e) {
    			System.out.println("  Catch");
    			e.printStackTrace();
    		}
    
    	}
    }

    실행 결과:
          
      Catch
    java.lang.InterruptedException
    	at com.feng.example.MyThread.run(MyThread.java:13)

    interrupt 수면 중 스 레 드
    1.스 레 드 는 sleep 에 들 어간 다음 interrupt
    정의 루틴 클래스:
    package com.feng.example;
    
    public class MyThread extends Thread {
    
    	@Override
    	public void run() {
    
    		try {
    			System.out.println("    ");
    			Thread.sleep(10000);
    			System.out.println("      ");
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}  //  10 
    		
    	}
    }

    테스트 클래스:
    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Thread thread = new MyThread();
    		thread.start();
    		try {
    			Thread.sleep(2000);
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		thread.interrupt();
    		
    	}
    
    }

    sleep 의 스 레 드 를 종료 하면 interrupted Exception 을 던 집 니 다.
    실행 결과:
        
    java.lang.InterruptedException: sleep interrupted
    	at java.lang.Thread.sleep(Native Method)
    	at com.feng.example.MyThread.run(MyThread.java:10)

    2.먼저 interrupted,스 레 드 다시 sleep 에 들 어가 기
    스 레 드 클래스 수정:
    package com.feng.example;
    
    public class MyThread extends Thread {
    
    	@Override
    	public void run() {
    
    		try {
    			//      ,
    			for(int i=0; i<10000; i++)
    			{
    				System.out.println(i);
    			}
    			System.out.println("    ");
    			Thread.sleep(10000);
    			System.out.println("      ");
    		} catch (InterruptedException e) {
    			// TODO Auto-generated catch block
    			System.out.println("  Catch");
    			e.printStackTrace();
    		}  //  10 
    		
    	}
    }

    테스트 클래스:
    package com.feng.example;
    
    public class ThreadTest {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		
    		Thread thread = new MyThread();
    		thread.start();
    		thread.interrupt();
    		System.out.println("end");
    		
    	}
    
    }

    실행 결과:
    9997
    9998
    java.lang.InterruptedException: sleep interrupted
    	at java.lang.Thread.sleep(Native Method)
    	at com.feng.example.MyThread.run(MyThread.java:15)
    9999
        
      Catch

    이 를 통 해 알 수 있 듯 이 먼저 sleep 재 interrupt 은 직접 이상 을 던 집 니 다.먼저 interrupt 을 한 다음 sleep 에 들 어가 면 sleep 시 이상 을 던 집 니 다.

    좋은 웹페이지 즐겨찾기