자바 멀티 스레드 프로그래밍의 00 00Java 수석

1 개 프로세스와 스레드

가장 큰 특징 중 당신이 멀티 스레드 포괄적이고 상세한 이해의 개념이없는 경우 때문에, 전체 자바 기술 내부 학습 멀티 스레드 개발을위한 자바 언어 지원 (멀티 스레드 프로그래밍 언어를 지원하는 몇 가지 중 하나)이며, 설계 과정의 미래에 수행 한 프로젝트 중, 특히 동시 액세스 디자인은 심각한 기술적 결함이 될 것입니다.

당신이 스레드가 총리 자체가 기능이 기존의 DOS 시스템의 시대에, 프로세스의 개념을 이해하는 데 필요한 무엇인지 알고 싶다면 : 당신은 당신의 컴퓨터에 바이러스에 표시하는 경우, 모든 프로그램은 실행 기존의 DOS 때문에되지 않습니다 치료 과정의 가장 중요한 기능은, 같은 기간 만 실행에서 프로그램을 수 있지만, 하나의 프로세스 처리를 사용하여.

당신이 시간의 기간에 동시에 여러 프로그램을 실행할 수 있습니다,이 프로그램은 자원을 점유 켜집니다, 그래서 순서로 같은 시간에 더 많은 프로그램이있을 것이다, 그래서 나중에 윈도우 시대는 멀티 프로세스 설계를 시작했다 프로세스의 어떤 양이 당신은 또한 싱글 코어 CPU의 처리 속도보다 더 가질 수 발생없는 경우에도 CPU가 다음, 더 처리 할 수 ​​있기 때문에 실행하지만, 시간에 동일한 지점에서만, 프로세스 실행, 나중에 멀티 코어 CPU가있을 것입니다 업그레이드 할 수 있습니다.

스레드 그래서 복수를 사용하는 경우, 프로세스 스레드보다 빠르게 프로세스의 지원에 따라 다르지만 시동 속도 그래서 스레드는 스레드를 생성하고, 처리에 기초하여 사용을 구분하는 과정에 기초하여 작은 프로그램 단위 인 그 때에 실행 프로세스보다 스레드의 동시 처리 성능. 프로세스는 운영 체제에 분할되고, 스레드는 프로세스에 나누어 져 있습니다.

자바는 높은 처리 성능을 달성 할 수있는 자바 처리에 대한 동시 액세스를 수행 할 때이므로, 멀티 스레드 프로그래밍 언어이다. 가 필요합니다, 우리는 주요 클래스 임무 스레드를 정의하는 전용 스레드가 필요에 자바 멀티 스레딩의 정의를 달성하고, 클래스의 몸을 정의하는 경우, 특정 인터페이스를 구현하거나 특정를 확장해야합니다 부모들은 완료 할 수 있습니다.

멀티 스레딩 2 스레드 클래스가 구현

이러한 클래스를 상속 한, 클래스 java.lang.Thread에 제공 자바는이 클래스가 클래스의 메인 스레드이다라고하지만, 클래스, 당신은 멀티 스레드 처리를 달성 할 수없는 의미합니까 때문에 커버 할 필요 () 메소드 (공공 무효 실행 ())에 의해 제공되는 스레드 클래스의 실행을 작성하고,이 방법은 메인 스레드 방법에 속한다.
예 : 멀티 스레딩 상속 스레드 클래스가 구현

//实现线程的主体类,继承Thread类
//实现线程主体方法run()
class MyThread extends Thread{  //继承Thread类,实现线程的主体类
	public String title;
	
	public MyThread() {}
	
	public MyThread(String title) {
		this.title = title;
	}
	
	@Override  //实现线程主体方法run()
	public void run() {
		for(int i = 0; i < 10; i++) {
			System.out.println(this.title + "  run: i=" + i);
		}
	}
	
	
}

그 클래스를 사용하는 경우, 정상적인 상황에서는, 다음 오브젝트의 인스턴스를 생성해야하며, 그 클래스를 호출하려면 : run () 메소드에 정의되어야 수행 될 기능들을 멀티 스레딩 주목해야한다 방법을 제공하지만, 여러 스레드가 시작 사용해야합니다 운영 체제를 시작하기 위해 그렇게 리소스 예약이 포함하기 때문에 실행 () 메소드를 직접 호출 할 수 없습니다 () 메소드가 완료 (공공 무효 시작 ()).
예 : 멀티 시작 스레드

public class ThreadDemo {

	public static void main(String[] main) {
		MyThread threadA = new MyThread("Thread-A");
		MyThread threadB = new MyThread("Thread-B");
		MyThread threadC = new MyThread("Thread-C");
		threadA.start();
		threadB.start();
		threadC.start();
	}
}

그것은 호출 () 메소드를 시작하지만,이 시간에 호출에 의해 발견 될 수 있지만, 궁극적으로 () 메소드를 실행 않으며, 모든 객체가 교대로 실행의 스레드된다. 그래서 왜 그냥 스레드가 운영하는 멀티 시작 할 () Thread 클래스의 시작을 사용해야합니다 방법 () 메서드를 사용? 다음은 start () 메서드 자료 분석입니다 :

public synchronized void start() {
    if (threadStatus != 0)    //线程状态判断
        throw new IllegalThreadStateException();

    group.add(this);

    boolean started = false;
    try {
        start0();  //在start()方法里面调用了start0()方法
        started = true;
    } finally {
        try {
            if (!started) {
                group.threadStartFailed(this);
            }
        } catch (Throwable ignore) {
           
        }
    }
}

private native void start0();  //只定义了方法名称,但是没有实现

시작 () 메소드 내부에서 찾을 수는 "예외 : IllegalThreadStateException"비정상적인 클래스 객체를 throw하지만, 전체 프로그램은 사용하지 않을가 발생하거나 명확한 시도 ... 예외가 RuntimeExcption 서브 클래스를해야하기 때문에 캐치 처리, 객체의 각 스레드 클래스를 않습니다 이 예외가 예를 들어, 다음 코드는 예외가 발생합니다, 슬로우됩니다 반복 시작하면 한 번만 시작 할 수 있습니다.

//重复进行线程的启动
package cn.victor.demo;

class MyThread extends Thread{  //继承Thread类,实现线程的主体类
	public String title;
	
	public MyThread() {}
	
	public MyThread(String title) {
		this.title = title;
	}
	
	@Override  //实现线程主体方法run()
	public void run() {
		for(int i = 0; i < 10; i++) {
			System.out.println(this.title + "  run: i=" + i);
		}
	}
	
	
}

public class ThreadDemo {

	public static void main(String[] main) {
		MyThread threadA = new MyThread("Thread-A");
		threadA.start();
		threadA.start();
		
	}
}

/*
Exception in thread "main"
java.lang.IllegalThreadStateException
	at java.base/java.lang.Thread.start(Unknown Source)
	at javasenior/cn.victor.demo.ThreadDemo.main(ThreadDemo.java:27)

*/

자바 프로그램의 실행 과정에서이 로컬 운영 체제 함수 호출을 지원하므로, 계정으로 개발자에 대한 수요의 다른 수준을,이는 JNI (Java 원시 인터페이스) 기술이라고하지만, 자바 개발 과정에서 이러한 사용을 권장하지 않습니다,이 기술의 사용은 우리가 제공하는 스레드 클래스의 기본 운영 체제의 일부 특수 치료의 기능을하지만, start0의 일부를 사용할 수있는 ()이 메소드는 다른 운영 시스템 구축의 필요성에 의존하고 있다고 말한다.

Thread 클래스의 start () 메서드 : 어떤 경우에, 한 다중 스레드, 다중 스레드 시작의 정의로 항상 한 프로그램입니다

3의 Runnable 인터페이스 다중 스레드를 달성

이를 달성하는 것이 가능하지만 멀티 스레드 그래서 자바 또한 제 멀티 스레딩의 주요 구조의 정의를 제공하고, 나사 상속에 의해 정의되지만 항상 상속 단일 상속있을 것이다 Java 프로그램은 한정 : 구현 java.lang.Runnable인터페이스 다음이 인터페이스를 정의한다 :

@FunctionalInterface  //从JDK 1.8引入Lambda表达式之后就变为了函数式接口
public interface Runnable{
    public void run();
}

예 : 메인 클래스는 Runnable를 통해 멀티 스레드 달성하기 위해

class MyThread implements Runnable{  //实现Runnable接口,实现线程的主体类
	public String title;
	
	public MyThread() {}
	
	public MyThread(String title) {
		this.title = title;
	}
	
	@Override  //实现线程主体方法run()
	public void run() {
		for(int i = 0; i < 10; i++) {
			System.out.println(this.title + "  run: i=" + i);
		}
	}
	
	
}

그러나,이 시간에이 상속되지 않기 때문에 스레드 부모 클래스, 다음 MyThread 클래스의이 시간을 더 이상 지원을 시작하지 () 메소드는이 상속하지만 Thread.start를 사용하지 않는 경우 () 메소드는 멀티 스레드 시작되지 않습니다 이 시간, 그래서 우리는이 제공하는 스레드 클래스 생성자 볼 필요가있다.
(1) 생성자 공용 실 (Runnable를 목표)
실시 예 시작 멀티 스레딩

public class ThreadDemo {

	public static void main(String[] main) {
		new Thread(new MyThread("Thread-A")).start();
		new Thread(new MyThread("Thread-B")).start();
		new Thread(new MyThread("Thread-C")).start();
		
	}
}

그래서이 경우에는 더 이상 단일 상속 스레드 메인 클래스가 국한되지만을 구현하는 실행 가능한 인터페이스 객체 이후, 찾을 수 있습니다이 시간 멀티 스레딩은,이 디자인은 표준 디자인이다.
직접적 람다 식을 스레드 클래스 구현을 사용할 수 있도록 JDK 1.8의 시작 부분에서 찾을 수 있습니다 Runable 인터페이스, 기능적인 인터페이스 정의를 사용합니다.
예 : 사용 람다 멀티 스레드

public static void main(String[] main) {
		for(int x = 0; x < 3; x++) {
			String title = "Thread-" + x;
			Runnable run = ()->{
				for(int y = 0; y < 10; y++) {
					System.out.println(title + " run: y=" + y);
				}
			};
			new Thread(run).start();
		}
	}

//*************************************
public static void main(String[] main) {
		for(int x = 0; x < 3; x++) {
			String title = "Thread-" + x;
			new Thread(()->{
				for(int y = 0; y < 10; y++) {
					System.out.println(title + " run: y=" + y);
				}
			}).start();
		}
	}

우선 순위는 향후 개발의 Runnable 인터페이스를 달성하는 것입니다, 멀티 스레드, 영원한는 Thread 클래스 객체에 의해 멀티 스레드를 시작하고있다.

Runnable를 4 스레드의 관계

그것은 하나의 피할 수 있기 때문에 확실히 그 자체에 관한 코드 구조에서의 Runnable를 사용하는 경우, 스레드 클래스의 Runnable 인터페이스를 가장 편리합니다 : 분석하는 일련의를 찾을 수 후, 이미 구현 프로세스 다중 스레드의 두 가지 방법이 있었다 상속 제한뿐만 아니라 더 나은 기능을 확장 할 수 있습니다.

그러나 우리는 또한 관찰하고 구조, 개방의 Thread 클래스 정의에서의 Runnable 접촉 스레드해야합니다

public class Thread extends Object implements Runnable{}

지금 찾기 클래스의 Runnable 인터페이스의 서브 클래스입니다 스레드, 그것은, Thread 클래스 시간이 실제로 덮어 쓰기 또는 이전의 Runnable 인터페이스의 run () 메소드되어 상속 프로그램의 계급 구조에서 보면이 시간이 너무.

프록시 디자인 패턴 구조, 사용자 정의하지만, 메인 쓰레드 프로젝트의 핵심 기능을 구현하기위한 책임이있다, 모든 보조 핸들에 Thread 클래스의 모든 구현을 사용하여 멀티 스레드 디자인.

통화 시간 동안 시작 스레드 멀티 스레드 start () 메서드이며, 다음 run () 메소드는, Thread 클래스의 생성자의 Runnable 인터페이스 객체를 통과 할 때, 그 객체가 Thread 클래스의 인터페이스가 될 것이다 것을 발견 클래스가 스레드의 run () 메소드를 호출 할 때 대상은 start () 메소드가 실행에 저장된 속성,이 run () 메소드가 실행 가능한 인터페이스 서브 클래스 코팅 작성 run () 메소드를 호출 할 수 있습니다.

멀티 스레딩 개발의 본질은 여러 스레드가 같은 리소스를 잡아 다음 메인 쓰레드 설명하고, 자원의 설명은 Runnable를 통해 이루어집니다 스레드 수 있다는 것입니다 본질적이다.


동시 액세스 자원 활용 티켓 프로그램은 여러 스레드를 구현 : 예

package cn.victor.demo;

class MyThread implements Runnable{  //实现Runnable接口,实现线程的主体类
	private int ticket = 5;
	
	@Override  //实现线程主体方法run()
	public void run() {
		for(int i = 0; i < 10; i++) {
			if(this.ticket > 0) {
				System.out.println("sale ticket" + this.ticket--);
			}
		}
	}
	
	
}

public class ThreadDemo {

	public static void main(String[] main) {
		Runnable thread = new MyThread();
		new Thread(thread).start();
		new Thread(thread).start();
		new Thread(thread).start();
	}
}

이 절차는도를 분석하여 상기 메모리의 구조를 분석하여 수행 하였다.

5 호출 인터페이스 스레딩

당신은 멀티 스레드 구현을 개발하려는 경우의 측면에서 가장 전통에서 것은 확실히에 의존해야 할 것이다 것은 Runnable를, 그러나의 Runnable 인터페이스는 하나의 단점이있다 : 스레드는 1.5 선물 새로운를 JDK에 다음에서 이렇게, 반환 값을 얻을 수 없습니다 완료되면 구현을 인터페이스 쓰레드 java.util.concurrent.Callable 인터페이스, 인터페이스 정의의 제 관찰 :

@FunctionalInterface
public interface Callable<V>{
	public V call() throws Exception;
}

당신이 혜택을 내리 뜬 보안 위험을 제공 피할 수 있도록, 반환이 타입의 데이터의 일반적인, 제네릭 형식을 설정할 수 있습니다 때 호출 정의를 찾을 수 있습니다.

예 : 호출 가능하여 멀티 스레드

package cn.victor.demo;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

class MyThread implements Callable<String>{

	@Override
	public String call() throws Exception {
		for(int i =0; i < 10; i++) {
			System.out.println("Thread run " + i);
		}
		return "Thread over";
	}
	
}

public class ThreadDemo {

	public static void main(String[] main)throws Exception {
		FutureTask<String> futureTask = new FutureTask<String>(new MyThread());
		new Thread(futureTask).start();
		new Thread(futureTask).start();
		
		System.out.println(futureTask.get());
	}
}

질문을 인터뷰 : 차이의 Runnable 및 호출 가능을 설명해주십시오?
(1)의 Runnable는 JDK 1.0의 다중 스레드 인터페이스를 구현하는 경우를 제시하고, 호출 가능는 JDK 1.5 후에 제시된다.
(2) java.lang.Runnable의 인터페이스는 단순히 run () 메소드와 없음 리턴 값 제공 중에서도,
인터페이스 java.util.concurrent.Callable 호출 () 메소드가 제공된다. (3), 리턴 값이있을 수있다;

상태를 실행 명 이상의 스레드

멀티 스레드의 개발, 프로그래밍의 과정에 따라 항상 : 다음 클래스는 스레드 스레드에 의해 시작 스레드의 주요 클래스를 정의하지만, start () 메서드를 호출하는 것을 의미하지 않는다, 스레드 및 실행, 스레딩의 전반적인 상태는 실행의 자신의 세트를 가지고 있기 때문이다.

1, 개체 스레드 클래스의 스레드가 포장에 사용되어야한다, 스레드 시작 ()을 시작하는 데 사용하지만, 시작 스레드의 수는 현재 상태 준비 상태로 설정되어 사실에서 수행되지 않고,
2 , 준비 상태를 입력 한 후, 당신은 상태 (run () 메소드)에 성공적으로 실행 후 스레드를 예약, 예약 자원 기다릴 필요가 있지만, 모든 때까지 스레드가 약간의 일시 정지를 할 수있는 중간 필요성을 실행할 수 없습니다 예를 들어, 상태 : 당신은 자원을 만들 필요가 일정 기간을 수행 한 후 스레드는 다음 스레드가 차단 된 상태를 입력하고 다시 준비 상태로 돌아가,
스레드, 사실, 3, 실행 () 메소드가 완료 주요 작업은 그래서 당신은 정지 상태로 바로 갈 수 끝날 것입니다.

게시 77 개 원래 기사 · 원의 찬양 (11) · 전망 2633

추천

출처blog.csdn.net/weixin_43762330/article/details/104703422