멀티스레딩 배경 지식 소개
멀티스레딩을 사용하면 모델을 단순화하고 강력한 코드를 작성할 수 있지만, 멀티스레딩을 작성하는 것은 쉽지 않으며 장기적인 연습 과정이 필요합니다.
① 프로세스: 프로그램(작업)의 실행 프로세스입니다. Dynamics
는 리소스(공유 메모리, 공유 파일)와 스레드를 보유합니다. Carrier
예: Eclipse, QQ
② 스레드:
Eclipse: 소스 코드 텍스트 편집, 소스 코드 컴파일, 구문 검증.
QQ: 문자 채팅, 파일 보내기 및 받기.
과정을 수업에 비유한다면 이 수업의 모든 학생은 스레드입니다. 학생은 학급의 가장 작은 단위이며 학급의 가장 작은 단위를 구성합니다. 한 학급에는 여러 명의 학생이 있을 수 있으며, 이 학생들은 모두 수업에서 동일한 테이블, 의자, 칠판 및 분필을 사용합니다.
스레드는 시스템에서 가장 작은 실행 단위입니다. 동일한 프로세스에는 여러 개의 스레드가 있으며 스레드는 프로세스의 리소스를 공유합니다.
상호 배제 및 동기화.
Java.lang
class Thread
interface Runnable
public void run()
category |
메서드 서명 |
소개 |
스레드 생성 |
Thread() |
|
Thread(문자열 이름) |
||
Thread(실행 가능한 대상 ) |
||
Thread(실행 가능한 대상, 문자열 이름) |
||
스레드 메소드 |
void start() |
스레드 시작 |
static void sleep(long millis) |
thread sleep |
|
static void sleep(long millis, int nanos) | ||
void Join() |
은 다른 스레드가 대기하도록 만듭니다. 현재 스레드 종료 oidVoid 조인 (Long Millis) |
|
Void 조인 (Long Millis, int Nanos) | ||
Static void aviled () | ||
스레드 참조 가져오기 |
||
현재 실행 중인 스레드 참조 반환 |
두 스레드가 아무런 처리도 하지 않을 때는 교대로 실행됩니다. 부울 유형을 사용하여 스레드의 루프를 제어하는 경우 변수 앞에 휘발성 키워드를 추가합니다. Volatile은 스레드가 다른 스레드가 작성한 값을 올바르게 읽을 수 있도록 보장합니다. 참고: sleep() 메서드의 기능: 지정된 시간 동안 스레드를 절전 모드로 만듭니다. join() 메소드의 역할: // 다른 스레드가 현재 스레드가 실행을 완료할 때까지 기다리게 합니다. 멀티 스레딩 사례예 1: 1 package com.czgo; 2 3 4 5 /** 6 7 * 线程先生 8 9 * @author 疯子 10 11 * 12 13 */ 14 15 public class Actor extends Thread { 16 17 @Override 18 19 public void run() { 20 21 //getName():获取当前线程的名称 22 23 System.out.println(getName()+"是一个演员!"); 24 25 //用来记录线程跑的次数 26 27 int count = 0; 28 29 boolean keepRunning = true; 30 31 while(keepRunning){ 32 33 System.out.println(getName()+"登台演出"+(++count)); 34 35 if(count==100){ 36 37 keepRunning = false; 38 39 } 40 41 if(count%10==0){ 42 43 try { 44 45 Thread.sleep(1000); 46 47 } catch (InterruptedException e) { 48 49 e.printStackTrace(); 50 51 } 52 53 } 54 55 } 56 57 System.out.println(getName()+"的演出结束了!"); 58 59 } 60 61 62 63 public static void main(String[] args) { 64 65 Thread actor = new Actor(); 66 67 //setName:设置线程的名称 68 69 actor.setName("Mr.Thread"); 70 71 //启动线程 72 73 actor.start(); 74 75 76 77 Thread actressThread = new Thread(new Actress(),"Ms.Runnable"); 78 79 actressThread.start(); 80 81 } 82 83 } 84 85 86 87 class Actress implements Runnable{ 88 89 @Override 90 91 public void run() { 92 93 //getName():获取当前线程的名称 94 95 //currentThread()获取当前线程的引用 96 97 System.out.println(Thread.currentThread().getName()+"是一个演员!"); 98 99 //用来记录线程跑的次数 100 101 int count = 0; 102 103 boolean keepRunning = true; 104 105 while(keepRunning){ 106 107 System.out.println(Thread.currentThread().getName()+"登台演出"+(++count)); 108 109 if(count==100){ 110 111 keepRunning = false; 112 113 } 114 115 if(count%10==0){ 116 117 try { 118 119 Thread.sleep(1000); 120 121 } catch (InterruptedException e) { 122 123 e.printStackTrace(); 124 125 } 126 127 } 128 129 } 130 131 System.out.println(Thread.currentThread().getName()+"的演出结束了!"); 132 133 }134 135 } 로그인 후 복사 예 2: 군대: 1 package com.czgo; 2 3 4 5 /** 6 7 * 军队线程 8 9 * 模拟作战双方的行为 10 11 * @author 疯子 12 13 * 14 15 */ 16 17 public class ArmyRunnable implements Runnable { 18 19 20 21 //volatile保证了线程可以正确的读取其他线程写入的值 22 23 //可见性 ref JMM,happens-before 24 25 volatile boolean keepRunning = true; 26 27 28 29 @Override 30 31 public void run() { 32 33 34 35 while(keepRunning){ 36 37 //发动5连击 38 39 for(int i=0;i<5;i++){ 40 41 System.out.println(Thread.currentThread().getName()+"进攻对方["+i+"]"); 42 43 //让出了处理器时间,下次谁进攻还不一定呢! 44 45 Thread.yield(); 46 47 } 48 49 } 50 51 52 53 System.out.println(Thread.currentThread().getName()+"结束了战斗!"); 54 55 56 57 } 58 59 } 로그인 후 복사 핵심 인물: 1 package com.czgo; 2 3 4 5 /** 6 7 * 关键人物 8 9 * @author 疯子 10 11 * 12 13 */ 14 15 public class KeyPersonThread extends Thread { 16 17 @Override 18 19 public void run() { 20 21 System.out.println(Thread.currentThread().getName()+"开始了战斗!"); 22 23 for(int i=0;i<10;i++){ 24 25 System.out.println(Thread.currentThread().getName()+"左突右杀,攻击随军..."); 26 27 } 28 29 System.out.println(Thread.currentThread().getName()+"结束了战斗!"); 30 31 32 33 } 34 35 } 로그인 후 복사 단계: 1 package com.czgo; 2 3 4 5 /** 6 7 * 隋唐演义大戏舞台 8 9 * @author win7 10 11 * 12 13 */ 14 15 public class Stage extends Thread { 16 17 18 19 @Override 20 21 public void run() { 22 23 System.out.println("欢迎观看隋唐演义"); 24 25 26 27 try { 28 29 Thread.sleep(5000); 30 31 } catch (InterruptedException e2) { 32 33 e2.printStackTrace(); 34 35 } 36 37 38 39 System.out.println("大幕徐徐拉开"); 40 41 42 43 try { 44 45 Thread.sleep(5000); 46 47 } catch (InterruptedException e2) { 48 49 e2.printStackTrace(); 50 51 } 52 53 54 55 System.out.println("话说隋朝末年,隋军与农民起义军杀得昏天暗地..."); 56 57 58 59 //隋朝军队 60 61 ArmyRunnable armyTaskOfSuiDynasty = new ArmyRunnable(); 62 63 //农民起义军 64 65 ArmyRunnable armyTaskOfRevolt = new ArmyRunnable(); 66 67 68 69 //使用Runnable接口创建线程 70 71 Thread armyOfSuiDynasty = new Thread(armyTaskOfSuiDynasty,"隋军"); 72 73 Thread armyOfSuiRevolt = new Thread(armyTaskOfRevolt,"农民起义军"); 74 75 76 77 //启动线程,让军队开始作战 78 79 armyOfSuiDynasty.start(); 80 81 armyOfSuiRevolt.start(); 82 83 84 85 //舞台线程休眠,大家专心观看军队的厮杀 86 87 try { 88 89 //Thread会指向当前类的线程 90 91 Thread.sleep(50); 92 93 } catch (InterruptedException e) { 94 95 e.printStackTrace(); 96 97 } 98 99 System.out.println("正当双方激战正酣,半路杀出了个程咬金"); 100 101 102 103 Thread mrCheng = new KeyPersonThread(); 104 105 mrCheng.setName("程咬金"); 106 107 108 109 System.out.println("程咬金的理想就是结束战争,使百姓安居乐业!"); 110 111 112 113 //停止军队作战 114 115 //停止线程的方法 116 117 armyTaskOfSuiDynasty.keepRunning=false; 118 119 armyTaskOfRevolt.keepRunning=false; 120 121 122 123 try { 124 125 Thread.sleep(2000); 126 127 } catch (InterruptedException e1) { 128 129 e1.printStackTrace(); 130 131 } 132 133 134 135 //历史大戏留给关键人物 136 137 mrCheng.start(); 138 139 140 141 try { 142 143 //使其他线程等待当前线程执行完毕 144 145 mrCheng.join(); 146 147 } catch (InterruptedException e) { 148 149 e.printStackTrace();150 151 } 152 153 154 155 System.out.println("战争结束,人民安居乐业,程先生实现了积极的人生梦想,为人民作出了贡献!"); 156 157 System.out.println("谢谢观看隋唐演义,再见!"); 158 159 } 160 161 162 163 public static void main(String[] args) { 164 165 new Stage().start(); 166 167 } 168 169 } 로그인 후 복사 스레드의 올바른 중지올바르게 멈추는 방법 Java 스레드: 부울 유형을 통해 루프 종료를 제어할 수 있습니다. not stop 메소드 stop() 메소드는 스레드를 갑자기 중지합니다. stop() 메서드는 스레드를 중지하는 잘못된 방법입니다. 스레드의 상호 작용Race Condition여러 스레드가 동시에 동일한 데이터(메모리 영역)에 대한 접근을 공유하는 경우, 각 스레드가 데이터를 연산하려고 하여 데이터가 손상(corrupted)되는 현상 , 이러한 현상을 경쟁 조건이라고 합니다. 상호 배제란 무엇인가요?상호 배제는 어떻게 이루어지나요?상호 배타적인 하나의 스레드로만 액세스할 수 있습니다. 상호 배제 구현: 동기화된(내재적 잠금) 잠금. 동기화 구현: wait()/notify()/notifyAll(). V Java 동시성에 대한 지식을 확장하는 방법 Java 메모리 모드JMM은 Java 스레드가 메모리를 통해 상호 작용하는 방법을 설명합니다. Happens-BEFORE SYNCHRONIZED, 휘발성 및 잠금 및 조건 Java 잠금 메커니즘 및 대기 대기 조건 조건 Java.util.concurrent.locks 구현 스레드 안전성 사용 사용 사용 사용 사용 s ‐ ‐ ‐ ‐ ‐ toDeadLocks멀티 스레드 프로그래밍을 위한 공통 상호 작용 모델 생산자- 소비자 모델 re 읽기-쓰기 잠금 모델 미래 모델 작업자 스레드 모델 Java.util.CURRENT 스레드 풀 Executorservice 미래 EUE에서 권장하는 두 권의 책: Core JavaJava 실제 동시성 두 가지 스레드 생성 방법 비교 Thread:① Thread 클래스 상속; Runnable:① Runnable 메서드는 Java 단일 상속 기능으로 인해 Thread 메서드를 피할 수 있습니다. 결함. ② 실행 가능한 코드는 여러 스레드(스레드 인스턴스)에서 공유할 수 있으며, 이는 여러 스레드가 동일한 리소스를 처리하는 상황에 적합합니다. Case:Thread: Runnable: 1 package com.czgo; 2 3 4 5 class MyThread extends Thread{ 6 7 8 9 private int ticketsCont = 5; //一共有5张火车票 10 11 12 13 private String name; //窗口,也即是线程的名字 14 15 16 17 public MyThread(String name){ 18 19 this.name = name; 20 21 } 22 23 24 25 @Override 26 27 public void run() { 28 29 30 31 while(ticketsCont>0){ 32 33 ticketsCont--; //如果还有票,就卖掉一张 34 35 System.out.println(name+"卖了1张票,剩余票数为:"+ticketsCont); 36 37 } 38 39 } 40 41 42 43 } 44 45 46 47 public class TicketsThread { 48 49 50 51 public static void main(String[] args) { 52 53 //创建3个线程,模拟三个窗口卖票 54 55 MyThread mt1 = new MyThread("窗口1"); 56 57 MyThread mt2 = new MyThread("窗口2"); 58 59 MyThread mt3 = new MyThread("窗口3"); 60 61 62 63 //启动这三个线程,也即是窗口,开始卖票 64 65 mt1.start(); 66 67 mt2.start(); 68 69 mt3.start(); 70 71 72 73 } 74 75 76 77 } 로그인 후 복사 1 package com.czgo; 2 3 4 5 class MyThread implements Runnable{ 6 7 8 9 private int ticketsCont = 5; //一共有5张火车票 10 11 12 13 @Override 14 15 public void run() { 16 17 18 19 while(ticketsCont>0){ 20 21 ticketsCont--; //如果还有票,就卖掉一张 22 23 System.out.println(Thread.currentThread().getName()+"卖了1张票,剩余票数为:"+ticketsCont); 24 25 } 26 27 28 29 } 30 31 32 33 } 34 35 36 37 public class TicketsRunnable { 38 39 40 41 public static void main(String[] args) { 42 43 44 45 MyThread mt1 = new MyThread(); 46 47 MyThread mt2 = new MyThread(); 48 49 MyThread mt3 = new MyThread(); 50 51 52 53 //创建三个线程来模拟三个售票窗口 54 55 Thread th1 = new Thread(mt1,"窗口1"); 56 57 Thread th2 = new Thread(mt2,"窗口2"); 58 59 Thread th3 = new Thread(mt3,"窗口3"); 60 61 62 63 //启动这三个线程,也即是三个窗口开始卖票 64 65 th1.start(); 66 67 th2.start(); 68 69 th3.start(); 70 71 72 73 } 74 75 76 77 } 로그인 후 복사 Thread 수명 주기 Illustration:Creation: Thread thd = new Thread()와 같은 새 스레드 개체를 만듭니다. Ready: 스레드 객체를 생성한 후 스레드의 start() 메서드가 호출됩니다. (참고: 현재 스레드는 스레드 대기열에 진입하여 CPU 서비스를 얻기를 기다리고 있으며 실행 조건이 있지만 반드시 실행을 시작한 것은 아닙니다). 실행 중: 준비 상태의 스레드가 CPU 리소스를 획득하면 실행 상태로 전환되고 run() 메서드의 논리 실행을 시작합니다. 종료: 스레드의 run() 메서드가 실행되거나 스레드가 stop() 메서드를 호출한 후 스레드는 종료된 상태로 들어갑니다. 블로킹: 특정 상황에서 실행 스레드는 어떤 이유로 일시적으로 CPU 리소스를 포기하고 자체 실행을 일시 중단하며 sleep() 메서드 호출과 같은 차단 상태에 들어갑니다.
스레드의 수호 성인 - 데몬 스레드 Java 스레드에는 두 가지 유형이 있습니다. 사용자 스레드: 포그라운드에서 실행되고 특정 작업을 수행합니다. 예를 들어 프로그램의 메인 스레드, 네트워크에 연결된 하위 스레드 등은 모두 사용자 스레드입니다. 데몬 스레드: 백그라운드에서 실행되고 다른 전경 스레드를 제공합니다.특징: 모든 사용자 스레드의 실행이 완료되면 데몬 스레드가 JVM과 함께 작업을 종료합니다.애플리케이션: 데이터베이스 연결 풀의 스레드 모니터링, JVM 가상 머신이 시작된 후 스레드 모니터링.가장 일반적인 데몬 스레드: 가비지 수집 스레드. |
위 내용은 Java 멀티스레딩에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!