자바 멀티 스레드 프로그래밍
자바 멀티 스레드 프로그래밍은 기본 지원을 제공한다. 다중 스레드 프로그램은 2 개 이상의 부분이 동시에 실행할 수 있습니다 포함되어 있습니다. 프로그램의 각 부분은 스레드라고하며, 각 스레드는 실행 별도의 경로를 정의합니다.
멀티 스레딩 멀티 태스킹, 멀티 스레딩의 특별한 형태이지만, 적은 자원의 오버 헤드를 사용한다.
운영 체제를 포함하는 프로세스에 하나 이상의 스레드를 포함 메모리 공간을 할당한다 : 프로세스 - 다른 용어는 본원에서 정의되고, 스레드는 관련. 별도의 스레드는 프로세스의 일부 여야, 존재할 수 없습니다. 프로세스는 스레드의 최종 실행 완료 될 때까지 모든 비 대기의 끝까지 실행하고있다.
멀티 스레딩은 전체 CPU 사용 목적에 도달하는 효율적인 프로그램을 작성하는 프로그래머를 만날 수 있습니다.
스레드의 생명주기
수명주기의 모든 단계를 통해 스레드. 다음 그림은 스레드의 전체 라이프 사이클을 보여줍니다.
- 새로운 상태 :
스레드 객체를 생성하는 새로운 키워드와 스레드 클래스 또는 서브 클래스를 사용한 후 스레드 객체는 새로운 상태에 있습니다. 이 프로그램 시작 ()이 thread 때까지이 상태를 유지합니다.
- 준비 상태 :
때 스레드 객체가 start () 메서드, 준비 상태로 스레드를 호출합니다. 준비 큐에 준비 스레드는 JVM 스레드 스케줄러 예약을 기다리는.
- 작동 상태 :
스레드가 CPU 자원의 준비 상태를 얻을 경우, 당신은이 시간에 실행 (), 쓰레드가 실행됩니다 수행 할 수 있습니다. 가장 복잡한 실행 스레드가 차단 상태, 준비 상태, 죽음의 상태가 될 수 있습니다.
- 차단 된 상태 :
스레드가 슬립 (슬립) 후에 실행되는 경우, 일시 정지 (중단)하고 다른 방법은 점유 된 자원의 손실은, 스레드의 실행 차단 상태로된다. 수면 시간은 다시 입력 준비 상태에 장비 나 자원을 얻기 위해 온 후.
- 죽음의 상태 :
태스크 또는 다른 종결 조건의 상태를 실행하는 스레드가 발생하는 경우, 스레드는 종료 상태로 전환된다.
스레드의 우선 순위
각 자바 쓰레드는 운영 체제 스레드 스케줄링 순서를 결정하는 데 도움이되는 우선 순위를 갖는다.
10 (Thread.MAX_PRIORITY) - Java 스레드의 우선 순위는 1 (Thread.MIN_PRIORITY) 범위의 정수이다.
기본적으로 각 스레드는 우선 순위 NORM_PRIORITY (5)가 할당된다.
더 높은 우선 순위 스레드는 프로그램보다 중요하며, 낮은 우선 순위의 스레드 전에 프로세서 자원을 할당한다. 그러나, 순서는 실행 스레드 우선 순위 스레드를 보장하고, 인터넷에 크게 의존하지 않는다.
스레드를 생성
자바는 스레드를 생성하는 두 가지 방법을 제공합니다 :
- 인터페이스를 구현하여 Runable;
- 상속 스레드 클래스 자체를 통해.
의 Runnable 인터페이스를 구현하여 스레드를 만들려면
스레드를 생성하는 가장 쉬운 방법은 Runnable 인터페이스를 구현하는 클래스를 만드는 것입니다.
Runnable를 달성하기 위해, 클래스는 메소드 호출의 실행 ()는 다음 내용을 수행 할 필요는 없다 :
public void run()
이 메소드를 오버라이드 (override) 할 수 있습니다, 실행 () 단지 주 스레드로, 다른 방법, 다른 클래스의 사용을 호출하고 변수를 선언 할 수 있습니다를 이해하는 것이 중요합니다.
클래스 만들기의 Runnable 인터페이스를 구현 한 후에는 클래스의 객체를 스레드를 인스턴스화 할 수 있습니다.
스레드, 여러 생성자를 정의 우리가 자주 사용하는이 다음과 같다 :
Thread(Runnable threadOb,String threadName);
여기서, threadOb은 실행 가능한 인터페이스를 구현하고, threadName 스레드의 새 이름을 지정하는 클래스의 인스턴스입니다.
새로운 스레드가 생성 된 후, 당신은 실행의 시작 () 메서드를 호출합니다.
void start();
예
다음은 스레드를 만들고 실행을 시작하는 그것의 인스턴스입니다 :
// 创建一个新的线程 class NewThread implements Runnable { Thread t; NewThread() { // 创建第二个新线程 t = new Thread(this, "Demo Thread"); System.out.println("Child thread: " + t); t.start(); // 开始线程 } // 第二个线程入口 public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Child Thread: " + i); // 暂停线程 Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); } } public class ThreadDemo { public static void main(String args[]) { new NewThread(); // 创建一个新线程 try { for(int i = 5; i > 0; i--) { System.out.println("Main Thread: " + i); Thread.sleep(100); } } catch (InterruptedException e) { System.out.println("Main thread interrupted."); } System.out.println("Main thread exiting."); } }
다음과 같이 위의 프로그램이 실행 컴파일
Child thread: Thread[Demo Thread,5,main] Main Thread: 5 Child Thread: 5 Child Thread: 4 Main Thread: 4 Child Thread: 3 Child Thread: 2 Main Thread: 3 Child Thread: 1 Exiting child thread. Main Thread: 2 Main Thread: 1 Main thread exiting.
상속 스레드를 통해 스레드를 만들려면
스레드를 생성하는 두 번째 방법은 Thread 클래스를 상속하는 새로운 클래스를 만든 다음 클래스의 인스턴스를 생성하는 것입니다.
상속 클래스는 새로운 스레드의 엔트리 포인트가되는 run () 메소드를 재정의해야합니다. 또한 start () 메서드가 실행 호출해야합니다.
예
// 通过继承 Thread 创建线程 class NewThread extends Thread { NewThread() { // 创建第二个新线程 super("Demo Thread"); System.out.println("Child thread: " + this); start(); // 开始线程 } // 第二个线程入口 public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Child Thread: " + i); // 让线程休眠一会 Thread.sleep(50); } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); } } public class ExtendThread { public static void main(String args[]) { new NewThread(); // 创建一个新线程 try { for(int i = 5; i > 0; i--) { System.out.println("Main Thread: " + i); Thread.sleep(100); } } catch (InterruptedException e) { System.out.println("Main thread interrupted."); } System.out.println("Main thread exiting."); } }
다음과 같이 위의 프로그램이 실행 컴파일
Child thread: Thread[Demo Thread,5,main] Main Thread: 5 Child Thread: 5 Child Thread: 4 Main Thread: 4 Child Thread: 3 Child Thread: 2 Main Thread: 3 Child Thread: 1 Exiting child thread. Main Thread: 2 Main Thread: 1 Main thread exiting.
스레드 방법
다음 표는 몇 가지 중요한 방법 Thread 클래스를 나열합니다 :
아니오. | 방법 설명 |
---|---|
(1) | 공공 무효 시작 () 실행을 시작하는이 스레드를 확인, Java 가상 머신이 스레드의 run 메소드를 호출합니다. |
이 | 공공 무효 실행 () 이 thread가 별개의 Runnable 실행 객체를 사용하여 생성 된 경우, 다음의 Runnable 객체의 run 메소드를 호출, 그렇지 않으면,이 방법은 아무 것도 반환하지 않습니다. |
3 | 공공 최종 빈에서는 setName (문자열 이름) 같은 매개 변수 이름 있도록,이 스레드의 이름을 변경합니다. |
4 | 공공 최종 무효 setPriority를 (INT 우선 순위) 스레드 우선 순위를 변경합니다. |
(5) | 공공 최종 무효 setDaemon를 (에 부울) 데몬 스레드 또는 사용자 스레드로이 스레드를 표시합니다. |
6 | 공공 최종 무효 가입 (긴 millisec) 밀리 밀리 세컨드의 최대 스레드 기다립니다. |
(7) | 공공 무효 인터럽트 () 중단 스레드. |
8 | 공공 최종 부울으로 isAlive () 이 thread가 활성화 된 경우. |
이 thread가 활성화 된 경우. 위의 방법은 Thread 객체라고합니다. 다음 방법은 Thread 클래스의 정적 방법이다.
아니오. | 방법 설명 |
---|---|
(1) | 공공 정적 무효 수율 () 현재 실행중인 스레드 객체를 일시 중단하고 다른 스레드를 수행합니다. |
이 | 공공 정적 무효 수면 (긴 millisec) 현재 (중단 실행) 잠을 스레드를 실행 밀리 초 지정된 수 이내의 정밀도 및 정확도에 의해이 운영 체제의 타이머와 스케줄러. |
3 | 공공 정적 부울 holdsLock (개체 X) 현재의 thread가 지정된 객체에 대한 모니터 락을 보관 유지하는 경우에만하고,이 경우에 true를 돌려줍니다. |
4 | 공공 정적 스레드 currentThread () 그것은 현재 실행중인 스레드 객체에 대한 참조가 반환합니다. |
(5) | 공공 정적 무효 dumpStack () 표준 오류 스트림에 대한 현재의 thread의 스택 트레이스를 인쇄합니다. |
예
다음 프로그램은 Thread 클래스 ThreadClassDemo 몇 가지 방법을 보여줍니다
// 文件名 : DisplayMessage.java // 通过实现 Runnable 接口创建线程 public class DisplayMessage implements Runnable { private String message; public DisplayMessage(String message) { this.message = message; } public void run() { while(true) { System.out.println(message); } } }
// 文件名 : GuessANumber.java // 通过继承 Thread 类创建线程 public class GuessANumber extends Thread { private int number; public GuessANumber(int number) { this.number = number; } public void run() { int counter = 0; int guess = 0; do { guess = (int) (Math.random() * 100 + 1); System.out.println(this.getName() + " guesses " + guess); counter++; }while(guess != number); System.out.println("** Correct! " + this.getName() + " in " + counter + " guesses.**"); } }
// 文件名 : ThreadClassDemo.java public class ThreadClassDemo { public static void main(String [] args) { Runnable hello = new DisplayMessage("Hello"); Thread thread1 = new Thread(hello); thread1.setDaemon(true); thread1.setName("hello"); System.out.println("Starting hello thread..."); thread1.start(); Runnable bye = new DisplayMessage("Goodbye"); Thread thread2 = new Thread(bye); thread2.setPriority(Thread.MIN_PRIORITY); thread2.setDaemon(true); System.out.println("Starting goodbye thread..."); thread2.start(); System.out.println("Starting thread3..."); Thread thread3 = new GuessANumber(27); thread3.start(); try { thread3.join(); }catch(InterruptedException e) { System.out.println("Thread interrupted."); } System.out.println("Starting thread4..."); Thread thread4 = new GuessANumber(75); thread4.start(); System.out.println("main() is ending..."); } }
결과는 다음과 같이 각각의 실행의 결과가 동일하지이다.
Starting hello thread... Starting goodbye thread... Hello Hello Hello Hello Hello Hello Hello Hello Hello Thread-2 guesses 27 Hello ** Correct! Thread-2 in 102 guesses.** Hello Starting thread4... Hello Hello ..........remaining result produced.
몇 가지 주요 개념을 스레드 :
프로그램을 다중 스레드 때 다음과 같은 개념을 이해할 필요가있다 :
- 스레드 동기화
- 스레드 사이의 통신
- 스레드 교착 상태
- 스레드 제어 : 일시 중지 및 재개
다중 스레드를 사용하여
멀티 스레드 프로그램의 효과적인 사용의 핵심은 동시 실행이 아니라 직렬 실행보다 이해입니다. 예를 들면 :이 프로그램은 두 개의 서브 시스템이 동시에 실행하면 멀티 스레드 프로그램을 활용하기 위해 필요한이 시간이 필요가 있습니다.
여러 스레드의 사용을 통해, 당신은 매우 효율적인 프로그램을 작성할 수 있습니다. 그러나 너무 많은 스레드를 생성하는 경우, 프로그램 실행의 효율성이 실제로 감소보다는 개선된다는 점에 유의하시기 바랍니다.
컨텍스트 스위치 오버 헤드가 너무 많은 스레드를 생성하는 경우, 프로그램의 실행 시간을 컨텍스트 스위칭에 소요 된 CPU 시간이 더 될 것입니다, 또한 매우 중요하다, 기억하십시오!