Java Multithreading 사용법에 대한 가장 포괄적 인 분석. Java의 멀티 스레딩 메커니즘에 대한 심층적 인 연구를 수행하지 않은 경우이 기사를 사용하면 Java 멀티 스레딩의 원리와 사용법을보다 철저하게 이해하는 데 도움이됩니다.
1. 스레드를 만듭니다
Java에서 스레드를 생성하는 두 가지 방법이 있습니다 : 스레드 클래스 사용 및 실행 가능한 인터페이스 사용. 실행 가능한 인터페이스를 사용하는 경우 스레드 인스턴스를 만들어야합니다. 따라서 스레드 클래스를 통해 스레드를 설정하든 실행 가능한 인터페이스를 설정하든 스레드 클래스 또는 하위 클래스의 인스턴스를 설정해야합니다. 스레드 생성자 :
방법 1 : 스레드 클래스 상속 및 실행 메소드를 덮어 씁니다.
public class threaddemo1 {public static void main (String [] args) {demo d = new demo (); d.start (); for (int i = 0; i <60; i ++) {system.out.println (thread.currentthread (). getName ()+i); }}} 클래스 데모 확장 스레드 {public void run () {for (int i = 0; i <60; i ++) {system.out.println (thread.currentthread (). getName ()+i); }}}방법 2 : 방법 2.
public class threaddemo2 {public static void main (String [] args) {demo2 d = new demo2 (); 스레드 t = 새 스레드 (d); t.start (); for (int x = 0; x <60; x ++) {system.out.println (thread.currentthread (). getName ()+x); }}} class demo2는 runnable {public void run () {for (int x = 0; x <60; x ++) {system.out.println (thread.currentthread (). getName ()+x); }}}2. 실의 수명주기
사람들이 출생, 노년, 질병 및 죽음을 가진 것처럼 실은 시작 (대기), 달리기, 일시 중단 및 중지의 네 가지 다른 상태를 겪어야합니다. 네 개의 상태는 모두 스레드 클래스의 메소드에 의해 제어 될 수 있습니다. 다음은 스레드 클래스 의이 4 개 상태와 관련된 방법입니다.
// 스레드를 시작합니다
publicvoid start ();
publicvoid run ();
// 스레드를 매달고 깨우십시오
publicvoid recume (); // 사용하지 않는 것이 좋습니다
PublicVoid Spelend (); // 사용하지 않는 것이 좋습니다
publicstaticvoid 수면 (긴 밀리 스);
publicstaticvoid 수면 (Long Millis, Int Nanos);
// 스레드를 종료합니다
publicvoid stop (); // 사용하지 않는 것이 좋습니다
publicVoid 인터럽트 ();
// 스레드 상태를 가져옵니다
publicboolean isalive ();
PublicBoolean은 중단 ();
PublicStaticBoolean Interrupted ();
// 메소드에 가입합니다
publicvoid join ()가 중단 된 소식을 던집니다.
스레드가 설정된 후에는 런 메소드에서 코드를 즉시 실행하지 않지만 대기 상태에 있습니다. 스레드가 대기 상태에 있으면 스레드 클래스 메소드를 사용하여 스레드의 우선 순위 (SetPriority), 스레드 이름 (SetName) 및 스레드 유형 (SetDaemon) 등과 같은 스레드의 다양한 속성을 설정할 수 있습니다.
시작 메소드를 호출 한 후 스레드는 실행 메소드에서 코드를 실행하기 시작합니다. 스레드는 실행중인 상태로 들어갑니다. 스레드 클래스의 isalive 메소드를 사용하여 스레드가 실행 상태인지 확인할 수 있습니다. 스레드가 실행중인 상태에 있으면 isalive가 true를 반환합니다. isalive가 false를 반환하면 실이 대기 상태 또는 정지 상태에있을 수 있습니다. 다음 코드는 스레드의 생성, 실행 및 중지의 세 상태 사이의 전환을 보여주고 해당 Isalive 리턴 값을 출력합니다.
스레드가 실행 메소드를 실행하기 시작하면 실행 메소드가 실행될 때까지 스레드가 종료되지 않습니다. 그러나 스레드를 실행하는 동안 스레드는 일시적으로 두 가지 방법으로 중지 될 수 있습니다. 이 두 가지 방법은 중단과 수면입니다. 스레드를 일시 중단 한 후 이력서 방법을 통해 스레드를 깨울 수 있습니다. 수면을 사용한 후에는 스레드가 설정 시간 후에 만 준비 상태에만 넣을 수 있습니다 (스레드가 잠들면 스레드가 즉시 실행되지 않을 수 있지만 준비 상태로 들어가서 시스템이 예약 될 때까지 기다립니다).
수면 방법을 사용할 때 주목해야 할 두 가지가 있습니다.
1. 수면 방법에는 두 개의 과부하 양식이 있습니다. 과부하 양식 중 하나는 밀리 초로 설정할 수있을뿐만 아니라 나노초 (1,000,000 나노초는 1 밀리 초입니다). 그러나 대부분의 운영 체제 플랫폼의 Java Virtual Machines는 나노초로 정확할 수 없으므로 나노초가 수면으로 설정되면 Java Virtual Machine 은이 값에 가장 가까운 밀리 초를 가져갑니다.
2. 수면 방법을 사용할 때는 던지기를 사용하거나 {…} catch {…}을 사용해야합니다. 런 메소드는 던지기를 사용할 수 없으므로 try {…} catch {…} 만 사용할 수 있습니다. 스레드가 잠자면 인터럽트 메소드를 사용하여 스레드를 방해 할 때 Sleep은 인터럽트 한 예외 예외를 던집니다. 수면 방법은 다음과 같이 정의됩니다.
PublicstaticVoid Sleep (Long Millis)는 중단 된 외과를 던졌습니다
PublicstaticVoid Sleep (Long Millis, Int Nanos)는 중단 예고를 던졌습니다
스레드를 종료하는 세 가지 방법이 있습니다.
1. 종료 플래그를 사용하여 스레드 종료를 정상적으로 나가게합니다. 즉, 실행 메소드가 완료되면 스레드가 종료됩니다.
2. 스톱 메소드를 사용하여 스레드를 강제로 종료하십시오 (이 방법은 중단 및 이력서와 동일하며 예측할 수없는 결과가있을 수 있으므로 권장되지 않습니다).
3. 인터럽트 방법을 사용하여 스레드를 방해합니다.
1. 종료 플래그를 사용하여 스레드를 종료하십시오
실행 방법이 실행되면 스레드가 종료됩니다. 그러나 때로는 실행 방법이 끝나지 않습니다. 예를 들어, 스레드를 사용하여 서버 프로그램의 클라이언트 요청 또는 루프 처리가 필요한 기타 작업을 듣습니다. 이 경우 이러한 작업은 일반적으로 while 루프와 같은 루프에 배치됩니다. 루프가 영원히 실행되기를 원한다면 (true) {…}를 사용할 수 있습니다. 그러나 특정 조건에서 while 루프 종료를 만들고 싶다면 가장 직접적인 방법은 부울 유형 플래그를 설정 하고이 플래그를 참 또는 거짓으로 설정하여 while 루프가 종료되는지 여부를 제어하는 것입니다. 다음은 종료 플래그를 사용하여 스레드를 종료하는 예입니다.
결합 메소드의 기능은 비동기 실행 스레드를 동기 실행으로 전환하는 것입니다. 즉, 스레드 인스턴스의 시작 메소드가 호출되면 메소드가 즉시 돌아옵니다. 시작 방법이 호출 된 후이 스레드에 의해 계산 된 값을 사용해야하는 경우 조인 메소드를 사용해야합니다. 조인 메소드를 사용하지 않으면 시작 방법 뒤의 명령문이 실행되면 스레드가 실행되도록 보장 할 수 없습니다. 결합 메소드를 사용한 후에는 스레드가 종료 될 때까지 프로그램이 실행되지 않습니다. 다음 코드는 조인 사용을 보여줍니다.
3. 멀티 스레드 안전 문제
문제의 원인 : 데이터를 공유하기 위해 동일한 스레드에서 여러 문장이 작동하는 경우, 한 스레드는 여러 문의 일부만 실행하지만 아직 실행되지 않았으며 다른 스레드는 실행에 참여하여 데이터를 공유하는 데 오류가 발생합니다.
솔루션 : 여러 작업과 데이터를 공유하는 여러 문의 경우 하나의 스레드 만 실행할 수 있습니다. 실행 프로세스 중에 다른 스레드는 실행되지 않습니다.
코드 블록 동기화 :
public class threaddemo3 {public static void main (String [] args) {ticket t = new ticket (); 스레드 t1 = 새 스레드 (t, "창 1"); 스레드 t2 = 새 스레드 (t, "창 2"); 스레드 t3 = 새 스레드 (t, "창 3"); 스레드 t4 = 새 스레드 (t, "창 4"); t1.start (); t2.start (); t3.start (); t4.start (); }} 클래스 티켓 구현 실행 가능 {private int ticket = 400; public void run () {while (true) {synchronized (new object ()) {try {thread.sleep (1); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } if (ticket <= 0) 브레이크; System.out.println (thread.currentthread (). getName ()+"--- 판매"+ticket--); }}}}동기 기능
public class threaddemo3 {public static void main (String [] args) {ticket t = new ticket (); 스레드 t1 = 새 스레드 (t, "창 1"); 스레드 t2 = 새 스레드 (t, "창 2"); 스레드 t3 = 새 스레드 (t, "창 3"); 스레드 t4 = 새 스레드 (t, "창 4"); t1.start (); t2.start (); t3.start (); t4.start (); }} 클래스 티켓 구현 실행 가능 {private int ticket = 4000; public synchronized void saleticket () {if (ticket> 0) system.out.println (thread.currentthread (). getName ()+"판매 된"+티켓-); } public void run () {while (true) {saleticket (); }}}동기 기능 잠금은이 정적 동기화 기능 잠금이 클래스입니다.
스레드 간의 커뮤니케이션
public class threaddemo3 {public static void main (String [] args) {class person {public String name; 개인 문자열 성별; public void set (문자열 이름, 문자열 성별) {this.name = name; this.gender = 성별; } public void get () {system.out.println (this.name+"...."+this.gender); }} 최종 사람 P = 새로운 사람 (); 새 스레드 (new runnable () {public void run () {int x = 0; while (true) {if (x == 0) {p.set ( "zhang san", "male");} else {p.set ( "lili", "nv");} x = (x+1)%2;}}); 새 스레드 (new runnable () {public void run () {while (true) {p.get ();}}). start (); }}/ *Zhang San .... Male Zhang San .... Male Lili .... nvlili .... Male Zhang San .... nvlili .... Male */위의 코드를 수정하십시오
public class threaddemo3 {public static void main (String [] args) {class person {public String name; 개인 문자열 성별; public void set (문자열 이름, 문자열 성별) {this.name = name; this.gender = 성별; } public void get () {system.out.println (this.name+"...."+this.gender); }} 최종 사람 P = 새로운 사람 (); 새 스레드 (new runnable () {public void run () {int x = 0; while (true) {synchronized (p) {if (x == 0) {p.set ( "zhang san", "male");} else {p.set ( "lili", "nv") x = (x+1)%2;}}}}}}}}}}}}}}}}}}}. 새 스레드 (new runnable () {public void run () {while (true) {synchronized (p) {p.get ();}}}}). start (); } /* lili .... nv lili .... nv lili .... nv lili .... nv lili ... San .... Male Zhang San .... Male */웨이크 업 메커니즘을 기다리고 있습니다
/**스레드 대기 웨이크 업 메커니즘*대기 및 깨우기는 동일해야합니다*/public class ThreadDemo3 {private static boolean flags = false; public static void main (String [] args) {class person {public String name; 개인 문자열 성별; public void set (문자열 이름, 문자열 성별) {this.name = name; this.gender = 성별; } public void get () {system.out.println (this.name+"...."+this.gender); }} 최종 사람 P = 새로운 사람 (); 새 스레드 (new runnable () {public void run () {int x = 0; while (true) {synchronized (p) {if (flags) try {p.wait ();} catch (InterpruptedException e) {// a auto-auto-auto-auto-auto-auto-Generated Catch E.PrintStackTrace (); if (x == 0) { "Zhang (x == 0)"; } {lili ","nv "}}; 새 스레드 (new runnable () {public void run () {while) {synchronized (p) {if (! flags) try {p.wait ();} catch (interpruptedExcept e) {// 자동 생성 된 캐치 블록 e.printstacktrace ();}; }).시작(); }}생산 및 소비 메커니즘
Public Class ThreadDemo4 {private static boolean flags = false; public static void main (string [] args) {클래스 상품 {개인 문자열 이름; 개인 int Num; public synchronized void produce (문자열 이름) {if (flags) try {wait (); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } this.name = name+"번호 :"+num ++; System.out.println ( "생산 ......"+this.name); 플래그 = 참이고; notifyall (); } public synchronized void 소비 () {if (! flags) try {wait (); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } system.out.println ( "소비 *****"+이름); 플래그 = 거짓; notifyall (); }} 최종 상품 g = 새로운 상품 (); 새 스레드 (new runnable () {public void run () {while (true) {g.proctor ( "product");}}). start (); 새 스레드 (new runnable () {public void run () {while (true) {g.consume ();}}). start (); }}생산 및 소비 메커니즘 2
Public Class ThreadDemo4 {private static boolean flags = false; public static void main (string [] args) {클래스 상품 {개인 문자열 이름; 개인 int Num; public synchronized void produce (문자열 이름) {while (flags) try {wait (); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } this.name = name+"번호 :"+num ++; System.out.println (thread.currentthread (). getName ()+"생산 ..."+this.name); 플래그 = 참이고; notifyall (); } public synchronized void cocume () {while (! flags) try {wait (); } catch (InterruptedException e) {// todo 자동 생성 캐치 블록 e.printstacktrace (); } system.out.println (Thread.currentThread (). getName ()+"소비 *******"+이름); 플래그 = 거짓; notifyall (); }} 최종 상품 g = 새로운 상품 (); 새 스레드 (new Runnable () {public void run () {while (true) {g.precture ( "product");}}, "product ("product ");}}},"product ( "product");}}, "product ("product ");}}},"product "}}}}}},"product ( "upplect"); }, "소비자 1 번". 소비 ******* 상품 번호 : 48050 제품 No. 1 제작 ... 상품 번호 : 48051 소비자 2 번 소비 **** 상품 번호 2 : 48051 자산 번호 2 생산 ... 48052 Consumer No. 2 소비자 ********** *** 상품 번호 : 48052 Producer Numbreed Hailited heabled habited heabled was heaked heaked heaked heaked has heaked has heaked has heaked has heaked has heaked had 48053 소비자 1 번 소비 ******* 상품 번호 : 48053 프로듀서 1 번 생산되었습니다 ... 상품 번호 : 48054 컨소더 2 번 소비 ******* 상품 번호 : 48054 프로듀서 2 번 생산되었습니다. 48055*/위는 Java 다중 스레드 정보의 편집입니다. 우리는 향후 관련 지식을 계속 추가 할 것입니다. 이 웹 사이트를 지원 해주셔서 감사합니다!