자바 --- (이론 프로그래밍) 멀티 스레딩

개념

1 프로그램 : 여러 조각으로 이루어진 특정 기능을 갖는 단계 및 사용의 시퀀스 해결
2 공정 : 프로그램 실행, 자원 할당의 최소 단위 인
CPU를 기본 스케쥴링 단위 3 스레드

댓글은 좋은 아래에 설명

아주 좋은 이야기가있다

보기의 응용 지점에서 기술적 인 세부 사항의 모든 종류에도 불구하고 :

==
1싱글 코어 컴퓨터있다자원은 병렬로 여러 프로그램에서 사용할 수 없습니다의 : CPU.
어떠한 경우 운영 체제에서,프로그램은 모든 CPU를 독점하고있다.
단독으로 프로그램에 의해 프로그램 A에 시간 CPU와 독점, B 다음 번에 CPU - 동일한 CPU를 공유하는 두 가지 작업이있는 경우, 프로그래머의 요구는 신중하게 실행 프로그램을 프로그램에 배치하는
이 배치 계획은 나중에 ", 즉,"스케줄러 "로 임명 개인의 이름입니다 OS의 핵심 요소가되었다스케줄러"실행 시트"그것은 단지의 한 부분으로 분할되어 하나의 CPU를 실행하는 방법에 관한 것이다 "테이크 회전용도에 다른 프로그램에 할당되고, 하이 레벨에서의 고속 스위칭 속도 분포하기 때문에, 생성물의 CPU에서 병렬로 다수의 프로그램을 생성한다.

도 2는 단일 코어 컴퓨터는 공유 자원하지만, 복수의 프로그램이 될 수있다문제로 이어질 것입니다 : 메모리를.
물리적 주소 0x100-0x1FF 절차 B 등 물리적 주소 0x00-0xff 프로그램 - 만 스케줄러, 아니 메모리 관리 구성 요소 운영 체제에서, 프로그래머는 수동으로 각 프로그램 실행을위한 공간을 마련 할 필요가있다.
그러나 이렇게 큰 문제가있다 : 메모리와 다른 공간을 사용하는 방법에 대한 좋은 토론을 조정하는 모든 프로그램이 사용자 정의 프로그램이 가능하지 않도록, 시스템 소프트웨어 및 하드웨어 시스템은 매우 다양합니다.

이 문제를 해결하기 위해, 컴퓨터 시스템 "소개가상 주소"개념은 세 가지 측면에서 시작합니까 :

2.1, 하드웨어, CPU는 대한 책임 MMU라는 특수 모듈을 추가가상 주소를 물리적사이트.

2.2,운영 체제인 메모리 관리 : 운영 시스템은 또 다른 핵심 구성 요소를 추가메모리 관리 모듈그것은 물리적 메모리, 거래의 가상 메모리 관련 시리즈를 관리합니다.

2.3 애플리케이션에서, 본 발명은 호출된다방법] 모델 (주 ==) 각 프로세스는 정확히 [] 가상 주소 공간과 동일하지만, 운영 체제 및 하드웨어 MMU 공동으로 다른 물리 어드레스 공간에 맵핑 ==. [다른] 공정은, 자신이실제 메모리의 독립적공간은 특별한 의미없이, 다른 프로세스의 물리적 메모리에 액세스 할 수 없습니다.

3, 지금,다른 응용 프로그램순서는 기본 물리적 메모리 할당에 대해 신경, 또는 CPU를 공유하는 조정을 걱정하지 않을 수 있습니다. 그러나 한 가지 문제가있다 :일부 프로그램이있다, 나는 공유 CPU에 원하는[또한] 동일한 물리적 메모리,이 시간,라는 사람을 공유 [] 모델에, 그러나, 그들은 그 과정에서 과거의 랩 자신을 얻을 수없는, 동일한 가상 주소 공간, 관리 스케줄러에서, 그들이 프로세스 내에서 포장 된, 주 CPU의 등장뿐만 아니라 동일한 물리적 주소 공간을 공유 프로세스의 물리적 주소 공간에 액세스하지 않습니다.

네, 어떻게 프로세스 그 사이의 동일한 물리적 주소 공간을 공유하는 방법을? POSIX 표준 운영 체제에 맞춰 여러 가지 방법으로 다른 시스템, 인터페이스, mmap에라는, 서로 다른 프로세스에 의해 공유 된 다른 프로세스에 물리적 주소 공간을 매핑 할 수 있습니다를 제공합니다.

5 PS : 일부 운영 체제에서, 처리 유닛을 스케줄링되지 않은 스레드 스케줄링의 기본적인 유닛이다 (즉, 스케줄러에 의해 사용될 수 없다), VxWorks와 같은 만 아니라 스케줄링 처리 스케줄러 스케줄 스레드

라이프 사이클의 스레드

  • 새로운 상태 :

스레드 객체와 새로운 키워드 Thread 클래스 또는 서브 클래스를 설정 한 후 스레드 객체의 새로운 상태입니다. 이 프로그램 시작 ()이 thread 때까지이 상태를 유지합니다.

  • 준비 상태 :

때 스레드 객체가 start () 메서드, 준비 상태로 스레드를 호출합니다. 준비 큐에서 준비 스레드는 JVM 스레드 스케줄러 일정을 기다리고.

  • 작동 상태 :

스레드가 CPU 자원의 준비 상태를 얻을 경우, 당신은이 시간에 실행 (), 쓰레드가 실행됩니다 수행 할 수 있습니다. 가장 복잡한 실행 스레드가 차단 상태, 준비 상태, 죽음의 상태가 될 수 있습니다.

  • 상태를 차단 :

스레드가 슬립 (슬립) 후에 실행되는 경우, 일시 정지 (대기 중) 등의 방법이 차지하는 리소스의 손실은, 스레드의 실행 차단 상태로된다. 수면 시간에 장비를 가져왔다 또는 자원은 준비 상태를 다시 입력 할 수 있습니다. 그것은 세 가지 유형으로 나눌 수 있습니다 :

차단 대기 : () 메소드를 실행 스레드가 대기 상태를 실행 스레드는 상태를 입력 기다리고 차단됩니다.

동기 차단 : (다른 스레드 동기화 잠금이 차지하기 때문에) 스레드 동기화 잠금 실패를 동기화 얻을.

기타 차단 다음 I / O 요청을 실행 스레드는 () 호출 스레드 잠을 (차단하여 상태를 입력) 또는 참여합니다. 수면 () 시간 제한, 종료하는 스레드에 대한 가입 () 대기 또는 제한 시간, 또는 내가 / O 처리가 완료되면, 다시 준비 상태로 스레드.

  • 죽음의 상태 :

태스크 또는 다른 종결 조건의 실 운전 상태는 스레드가 최종 상태로 전환하고, 발생한다.

스레드 우선 순위

우선 순위가 높은 스레드 프로그램에 더 중요하고, 우선 순위의 스레드를 낮추기 전에 프로세서 자원을 할당해야한다. 그러나 순서는 실행 스레드 우선 순위 스레드를 보장하지 않습니다, 또한 플랫폼에 매우 의존.

이것은 좋은 소개입니다

스레드의 우선 순위는 단지 이론적 인 우선, 높은 우선 순위 스레드가 실행되는 특정 스레드 컴퓨터에 의해 제어되는 약간 큰 제 실행 가능성이 있지만, 허용 할 수있다. 우리 모두 알다시피, 실행 스레드에 대한 컴퓨터는이 프로그램이 완전히 순서를 제어 할 수 있도록 실행 누구든지 잡을 수 선제 전략이다.

의 일부에서 질문과 답변 :

1, 가장 높은 우선 순위를해야한다는 것을 의미하지 않는다 높은 우선 순위는 작업을 통해 우선 순위를하도록하는 것입니다. 그렇지 않으면, 같은 이치 멀티 스레딩 없습니다.
동일한 조건에서 확률이 내가 가상 머신의 정책 봐, 그래서 어떻게 특정 과제로, 낮은보다 더 높은 우선 순위를 실행하는 것이 우선 순위가 높은 수단. 그러나 확실히 당신이 그들이 낮은 우선 순위 실행이 완료 때까지, 높은 우선 순위를 실행할 원하는대로

이 모든, 첫 번째 스레드 우선 순위가 더 높은 우선 순위가 더 많은 CPU 시간을 할당 보장하지 않습니다, 먼저 실행 더 높은 우선 순위를 보장하지 않지만, 최종 실행에서, 운영 체제에 의해 결정되는 시스템, 권장했다 자바는 마지막 말 없습니다.
또한 자바에서 할 수있는 유일한 보증은 내부 스레드에서 코드의 실행 순서 것으로 보인다 및 다른 스레드는이 코딩은 주문에 따라 수행에서 보이는 것을 보장 할 수 없습니다.

3, 자바 언어 사양, 프로그램의 정확성 및 성능 보증에 따라, 우리는 우선 순위를 의존 할 수 없다.
자신의 제어 프로그램에 의존하고있다.
우선 순위는 일반적으로 부족한 시스템 리소스에서이 점은 더 분명 할 수있다.
최적화 후,이를 통해 조금을 실행합니다.
그래서하지 매니페스트.

스레드를 생성

자바는 스레드를 만들 수있는 세 가지 방법을 제공합니다 :

  • 된 Runnable 인터페이스를 구현하는 단계;
  • 상속 스레드 클래스 자체를 통해;
  • 호출 가능와 미래를 통해 스레드를 만듭니다.

의 Runnable 인터페이스를 구현하여 스레드를 만들려면

class RunableDemo implements Runnable{
	
	private Thread t;
	private String name;
	
	RunableDemo(String name){
		
		this.name = name;
		System.out.println("create:"+this.name);
		
	}
	
	public void run(){
		int i;
		try{
			for(i=4;i>0;i--){
			System.out.println("run Thread:"+this.name+","+i);
			System.out.println("sleep:"+this.name+","+i);
			Thread.sleep(50);
			
			}
		}catch(InterruptedException e){
			
			System.out.println("interrupted:"+name);
		}
		
		System.out.println("exiting:"+this.name);
			
	}
	
	public void start(){
		
		System.out.println("--------");
		System.out.println("Thread start:"+this.name);
		if(t==null){
			t = new Thread(this,name);//创建名为name的thread
			t.start();//不是上面的start();
		}
	}
}


public class ThreadTest{

	public static void main(String[] args){
		
		RunableDemo r1 = new RunableDemo("gyy1");
		//r1.t = new Thread("gyy1");//错误,不能访问private
		
		r1.start();
		
		RunableDemo r2 = new RunableDemo("gyy2");
		
		
		r2.start();
	}
}

결과 : 먼저 끝을 gyy2 수, 일단이 gyy1 수 있습니다.

E:\java_code\code>java ThreadTest
create:gyy1
--------
Thread start:gyy1
create:gyy2
--------
run Thread:gyy1,4
Thread start:gyy2
sleep:gyy1,4
run Thread:gyy2,4
sleep:gyy2,4
run Thread:gyy1,3
run Thread:gyy2,3
sleep:gyy1,3
sleep:gyy2,3
run Thread:gyy1,2
sleep:gyy1,2
run Thread:gyy2,2
sleep:gyy2,2
run Thread:gyy2,1
run Thread:gyy1,1
sleep:gyy2,1
sleep:gyy1,1
exiting:gyy2
exiting:gyy1

상속 스레드를 통해 스레드를 만들려면

//class RunableDemo implements Runnable{

class RunableDemo extends Thread{	
	private Thread t;
	private String name;
	
	RunableDemo(String name){
		
		this.name = name;
		System.out.println("create:"+this.name);
		
	}
	
	public void run(){
		int i;
		try{
			for(i=4;i>0;i--){
			System.out.println("run Thread:"+this.name+","+i);
			System.out.println("sleep:"+this.name+","+i);
			Thread.sleep(50);
			
			}
		}catch(InterruptedException e){
			
			System.out.println("interrupted:"+name);
		}
		
		System.out.println("exiting:"+this.name);
			
	}
	
	public void start(){
		
		System.out.println("--------");
		System.out.println("Thread start:"+this.name);
		if(t==null){
			t = new Thread(this,name);//创建名为name的thread
			t.start();//不是上面的start();
		}
	}
}


public class ThreadTest{

	public static void main(String[] args){
		
		RunableDemo r1 = new RunableDemo("gyy1");
		//r1.t = new Thread("gyy1");//错误,不能访问private
		
		r1.start();
		
		RunableDemo r2 = new RunableDemo("gyy2");
		
		
		r2.start();
	}
}

프로그램

그렇지 않은 정지주기가 계속 동일하지 않을 경우 (1), 디지털 입력 키보드, 디지털 컴퓨터주고 환상 난수는 입력이 같은지 여부를 확인한다.


import java.util.Scanner;
class GuessTest extends Thread{
	
	private int number;
	GuessTest(int number){
		
		this.number = number;
		System.out.println("number:"+this.number+",yes or not?");
	}
	
	public void run(){
		
		int guess;
		int count=0;
		
		do{
			guess =(int)(Math.random()*100+1);
			System.out.println(this.getName()+" guess:"+guess);
			count++;
			
		}while(guess!=this.number);
			
		System.out.println("okok!yes:"+this.getName()+":guess:"+guess+",count:"+count);;
	}
}
public class GuessNumber{

	
	public static void main(String[] args){
		
		int i=0;
		Scanner s = new Scanner(System.in);
		System.out.println("请输入你的预测数字(整数):");
		
		
		
		if(s.hasNextInt()){
			
			i = s.nextInt();
			
			System.out.println("输入整数:"+i);
		}else{
			System.out.println("输入的不是整数。");
		}
		
		GuessTest g = new GuessTest(i);
		g.start();
		
	}
}

(2) 멀티 스레딩 방법을 사용하여 다음 방식 각각 포함하는 스레드 실행을

//需要Thread与start
//采用Runnable接口

public class DisplayMessage implements Runnable{
	
	private String mge;
	
	DisplayMessage(String mge){
		
		this.mge = mge;
	}
	
	public void run(){
		
		System.out.println(mge);
		System.out.println(mge);
		// while(true){
			
			// System.out.println(mge);
		// }
	}
}

//采用Thread类
class GuessANumber extends Thread{
	
	private int number;
	GuessANumber(int number){
		
		this.number = number;
		System.out.println("number:"+this.number+",yes or not?");
	}
	
	public void run(){
		
		int guess;
		int count=0;
		
		do{
			guess =(int)(Math.random()*100+1);
			System.out.println(this.getName()+" guess:"+guess);
			count++;
			
		}while(guess!=this.number);
			
		System.out.println("okok!yes:"+this.getName()+":guess:"+guess+",count:"+count);;
	}
}



public class ThreadClassDemo{
	
	public static void main(String[] args){
		
		// //Runnable
	  // Runnable hello = new DisplayMessage("Hello");
      // Thread thread1 = new Thread(hello);
      // thread1.setDaemon(true);
      // thread1.setName("hello");
      // System.out.println("Starting hello thread...");
      // thread1.start();
		
		
		DisplayMessage r1 = new DisplayMessage("gyy1");
		Thread th1 = new Thread(r1);
		th1.setDaemon(true);
		System.out.println("start "+th1.getName()+" Thread……");
		th1.setName("ggyy1");
		System.out.println("start "+th1.getName()+" Thread……");
		th1.start();//打印的是mge不是name
		
		
		Runnable r2 = new DisplayMessage("gyy2");
		Thread th2 = new Thread(r2);
		th2.setPriority(Thread.MIN_PRIORITY);
		th2.setDaemon(true);
		System.out.println("start "+th2.getName()+" Thread……");
		th2.start();
		
		//Thread
		GuessANumber g1 = new GuessANumber(9);
		System.out.println("Starting "+g1.getName()+"...");
		g1.start();
		
		try{//去掉会使得可能g2先执行。
			g1.join();
		}catch(InterruptedException e){
			System.out.println("Thread interrupted.");
		}
		GuessANumber g2 = new GuessANumber(17);
		System.out.println("Starting "+g2.getName()+"...");
		g2.start();
		
		
		System.out.println("main() is ending...");
		
	}
}

3 스레드 실행 순서 있도록

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadDemo3{
	
	public static void main(String[] args){
		
		method3();
	}
	
	private static void method3(){
		
		final Thread t1 = new Thread(new Runnable(){
			@Override
			public void run(){
				System.out.println("111");
			}
		});
		
		final Thread t2 = new Thread(new Runnable(){
			@Override
			public void run(){
				System.out.println("222");
			}
		});
		
		final Thread t3 = new Thread(new Runnable(){
			@Override
			public void run(){
				System.out.println("333");
			}
		});
		
		//创建一个newSingleThreadExecutor的线程池
		ExecutorService ss = Executors.newSingleThreadExecutor();
		//队列,先进先出
		ss.submit(t1);
		ss.submit(t2);
		ss.submit(t3);
		ss.shutdown();
		
		
		
		
	}
}

호출 가능와 미래를 통해 스레드를 만듭니다

호출 인터페이스 구현 클래스를 생성하고, clall () 메소드를 얻을 수 있습니다. 그리고 사용 FutureTask 클래스 호출 가능 래퍼 객체 구현 클래스 및 대상 스레드 객체로서이 FutureTask 객체의 스레드를 만들 수 있습니다.

특히 :

  1. 호출 인터페이스 구현 클래스를 생성 및 구현 호출 () 방법, 실행 스레드, 및 리턴 값으로서 ()를 호출하는 방법.
  2. () 메소드에 대한 호출이 리턴 값 호출 가능 FutureTask 객체를 캡슐화 객체 포장 호출 가능 FutureTask 클래스 객체를 이용하여 구현 된 클래스의 인스턴스를 생성 호출.
  3. 대상 개체로 사용 FutureTask 스레드 객체를 생성하고 새 스레드를 시작합니다.
  4. 통화 FutureTask 오브젝트 GET () 메소드는 서브 스레드 실행 종료 후 반환 값을 얻는다.
//采用Callable和Future创建线程

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class CallableDemo implements Callable<Integer>{//创建Callable接口的实现类
	
	public static void main(String[] args){
		
		int i;
		
		CallableDemo cc = new CallableDemo();//创建Callable接口的实现类的对象
		
		FutureTask<Integer> ff = new FutureTask<Integer>(cc);//用FutureTask来包装Callable对象
		
		for(i=0;i<100;i++){
			
			System.out.println("线程:"+Thread.currentThread().getName()+"i的值:"+i);
			
			if(i==20){
				Thread tt = new Thread(ff,"gyy");//Future对象创建线程
				tt.start();
			}
			
		}
		System.out.println("循环结束");
		
		try{
			System.out.println("线程返回值:"+ff.get());//返回call里的返回值
		}catch(InterruptedException e){
			e.printStackTrace();
		}catch(ExecutionException e){
			e.printStackTrace();
		}
		
		
		
	}
	
	
	
	//call返回值
	@Override
	public Integer call() throws Exception{
		int j;
		for(j=0;j<100;j++){
			
			System.out.println("线程:"+Thread.currentThread().getName()+"j值:"+j);
		}
		return j;
		
	}
}


오류 :

E:\java_code\code>javac CallableDemo.java
CallableDemo.java:31: 错误: 找不到符号
                }catch(ExecutionException e){
                       ^
  符号:   类 ExecutionException
  位置: 类 CallableDemo
1 个错误

해결 방법 :

将 ExecutionException 改成 Exception

스레드를 만들 수있는 세 가지 방법의 비교

  1. Runnable를, 호출 인터페이스 수단, 스레드 클래스가 구현하는 인터페이스 Runnable하거나 호출 인터페이스를 달성하기 위해 여러 스레드를 생성 사용하는 경우, 당신은 또한 다른 클래스에서 상속 할 수 있습니다.
  2. 당신은 다중 스레드를 사용 상속 스레드 클래스를 만들 때 현재 스레드에 액세스해야하는 경우, 간단한, 준비, 당신은 현재의 thread를 얻을 수는 Thread.currentThread () 메서드를 직접 사용이를 사용할 필요가 없습니다.

스레드의 몇 가지 주요 개념

멀티 스레드 프로그램에서 다음과 같은 개념을 이해할 필요가있다 :

스레드 동기화

스레드 간 통신

스레드 교착 상태

, 정지 및 이력서를 중단 : 제어 스레드

여러 스레드를 사용하여

멀티 스레딩의 효과적인 사용의 핵심은 동시에보다는 순차적으로 수행보다 실행되는 프로그램을 이해하는 것입니다. 예를 들어, 두 개의 서브 프로그램 동시 실행을 필요로하면 멀티 스레드 프로그램을 활용하기 위해 필요한이 시간이 있습니다.

여러 스레드를 사용하여 매우 효율적인 프로그램을 작성할 수 있습니다. 그러나 너무 많은 스레드를 생성하는 경우, 프로그램 실행의 효율성이 실제로 감소보다는 개선되고 있음을 참고하시기 바랍니다.

컨텍스트 스위칭 오버 헤드가 너무 많은 스레드를 만들 경우, CPU 시간은 프로그램의 실행보다 컨텍스트 스위칭 시간을 보냈다도 매우 중요하다, 기억하십시오!

게시 12 개 원래 기사 · 원 찬양 한 · 전망 (110)

추천

출처blog.csdn.net/weixin_43351473/article/details/104415656