JAva 7同時初級学習記録(1)


1.認識スレッド:
スレッドには2つの起動方式があり,1つはRunnableインタフェースを実装し,もう1つはThreadクラスを継承する.
public class JavaCurrent {

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


class InnerThread implements Runnable{

	@Override
	public void run() {
		//do something
	}
	
}

-----------------------------------------   -------------------------------------------

public class JavaCurrent {

	public static void main(String[] args) {
		InnerThread iThread = new InnerThread();
		iThread.start();
	}
}


class InnerThread extends Thread{

	@Override
	public void run() {
		//do something
	}
}

2.スレッドには独自の属性があります.
各スレッドには独自のプロパティがあり、これらのプロパティは、それらをよりよく区別したり、ステータスを観察したりするのに役立ちます.
スレッドにはid,name,Priority(優先度),status(ステータス)がある.
idとnameはその名の通りthread作用を示す.優先度は0-10に分けられ、級数が高いほど優先度が高くなる.ステータスは比較的重要で、以下のいくつかがあります.
新(初期化)、runnable(運転)、blocked(渋滞)、waiting(待機)、terminated(死亡).詳しいことは後で説明します.
3.スレッドを中断します.
スレッドThreadには、自身がブレークされたかどうかを検証するメソッドメカニズムがあり、isInterrupted()メソッドによって現在の実行スレッドがブレークされたかどうかを検出します.thread.interrupt()はスレッドを中断しますが、不思議なことに、1つのスレッドが実行されている間に、この方法を呼び出すのはまったく効果がありません.
public class JavaCurrent {

	public static void main(String[] args) {
		Thread thread = new Thread(new BeInterruptThread());
		thread.start();
		try {
			Thread.sleep(3000);
		} catch (Exception e) {
			e.printStackTrace();
		}
		thread.interrupt();
	}
	
	
}

class BeInterruptThread extends Thread{

	@Override
	public void run() {
		while(true){
			if(isInterrupted()){
				System.out.println("thread has been Interrupted");
				break;
			}else{
				System.out.println("always running");
			}
		}
	}
	
}

「thread has been Interrupted」は永遠に印刷されません...
問題は、isInterrupted()メソッドでは、親クラスのisInterrupted()メソッドを直接呼び出すと推定され、親クラスのinterruptプロパティ値を取得するだけで、BeInterruptThreadオブジェクトのinterruptプロパティではなく、ここでは
        @Override
	public void run() {
		while(true){
			if(Thread.currentThread().isInterrupted()){
				System.out.println("thread has been Interrupted");
				break;
			}else{
				System.out.println("always running");
			}
		}
	}

スレッドが中断されたり、ブロックされたりしたときにスレッドの終了を行う必要がある場合があります.この場合、InterruptedExceptionを放出して実現する必要があります.
4.現在実行中のスレッドを暫定的に
スレッドを一定期間実行させて一時停止させ、しばらくしてから再び走らせたい場合があります.周期的な操作業務ではよく見られます.
sleep()メソッドを使用できます.
public class JavaCurrent {

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

class SleepThread implements Runnable{

	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			try {
				TimeUnit.SECONDS.sleep(1);//     
			} catch (InterruptedException e) {
				System.out.println("mission failed");
				break;
			}
			System.out.println("i am counting:" + i);
		}
	}

}

またスレッドがsleepのときにinterruptに遭遇するとInterruptedExceptionがそのまま投げ出され、sleepの終了を待つことはありません.
5.メインスレッドを待機させる
この考え方は実は非同期のスレッドを同期スレッドに変えることで、不思議ですね.新しいスレッドを開くときは、実行スレッド(プライマリスレッド)に新しいスレッドの実行が完了するまで待機させ、続けます.一般的に初期化された場所で使用されます.
Threadクラスのjoin()メソッドを使用できます
public class JavaCurrent {

	public static void main(String[] args) {
		Thread thread1 = new Thread(new JoinThread1(),"first");
		Thread thread2 = new Thread(new JoinThread2(),"second");
		thread1.start();
		thread2.start();
		try {
			thread1.join();
			thread2.join();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("    ");
	}
	
	
}

class JoinThread1 implements Runnable{

	@Override
	public void run() {
		
		System.out.println("begin "+Thread.currentThread().getName()+" run()");
		try {
			TimeUnit.SECONDS.sleep(4);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("end "+Thread.currentThread().getName()+" run()");
	}

}

class JoinThread2 implements Runnable{

	@Override
	public void run() {
		System.out.println("begin "+Thread.currentThread().getName()+" run()");
		try {
			TimeUnit.SECONDS.sleep(6);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("end "+Thread.currentThread().getName()+" run()");
	}

}

6.スレッドに異常を投げ出す
run()法では捕捉された異常を投げ出すことができず,方法を変えることができることを知った.UncaughtExceptionHandlerを使用します.
public class JavaCurrent {

	public static void main(String[] args) {
	    Task task = new Task();
	    Thread thread = new Thread(task);
	    thread.setUncaughtExceptionHandler(new ThreadUnCaughtExceptionHandler());
	    thread.start();
	}
}


class Task implements Runnable{

	@Override
	public void run() {
		int isnum = Integer.parseInt("TTT");
	}
	
}

public class ThreadUnCaughtExceptionHandler implements UncaughtExceptionHandler{

	@Override
	public void uncaughtException(Thread t, Throwable e) {
	    
	    System.out.printf("Thread: %s
",t.getId());     e.printStackTrace(); } }

7.ローカルスレッド変数
複数のスレッドが同時に1つのタスクオブジェクトを実行する場合、タスクオブジェクトのプロパティを同時に使用することは許されません.簡単な方法でlocal .ローカルスレッド化が必要な変数を次のように宣言します.
static ThreadLocaltl=new ThreadLocal()でよい.これにより、各スレッドには独自のプロパティがあり、互いに干渉されません.
8.スレッドグループ管理
1つのスレッドのセットを統一的に管理する場合、例えば、いくつかのスレッドがターゲットを探しに行き、そのうちの1つがターゲットを見つけたら、情報をフィードバックし、他のすべてのスレッドを終了する可能性があります.ここではThreadGroupの例を示します.
public class JavaCurrent {

	public static int num = 1345; 
	
	public static void main(String[] args) {
		
		NumGenerate ng = new NumGenerate(1000);
		int[][] array = ng.getDoubleArrray();
		//     
		ThreadGroup threadGroup = new ThreadGroup("Search");
		for (int i = 0; i < 5; i++) {// 5   
			SearchThread st = new SearchThread(threadGroup,i+"", array);
			st.start();
		}
		waitFinish(threadGroup);
	}
	
	private static void waitFinish(ThreadGroup threadGroup) {
		while(true){
			if(threadGroup.activeCount() < 5){//            5  ,              
				threadGroup.interrupt();
		    	        break;
			}
			//       ,  5           ,       
			Thread[] threads = new Thread[threadGroup.activeCount()];
			threadGroup.enumerate(threads);
			int isSleepCount = 0;
			for (int i = 0; i < threads.length; i++) {
				if(threads[i].getState() == State.TIMED_WAITING){
					isSleepCount++;
				}
			}
			if(isSleepCount == 5){//  5       
				threadGroup.interrupt();
				System.out.println("all threads are not found !");
				break;
			}
		}
	}
}
public class SearchThread extends Thread{

	private String name;//         
	private int[][] targetArea;//    
	
	public SearchThread(ThreadGroup tg ,String name,int[][] targetArea) {
		super(tg, name);
		this.name = name;
		this.targetArea = targetArea;
	}
	
	@Override
	public void run() {
		int i = Integer.parseInt(this.name);//           
		for (int j = 0; j < this.targetArea[i].length; j++) {
			if(this.targetArea[i][j] == JavaCurrent.num){//       
				System.out.println("thread"+this.name+": find the number!-->" + this.targetArea[i][j]+"==============================="); 
				return;
			}
		}
		try {
			TimeUnit.MINUTES.sleep(MIN_PRIORITY);//    1  
		} catch (InterruptedException e) {
			System.out.println("thread" +this.name+ ":quit!");
		}
	}
}
/**
 *          
 *      size 1000,     0-2000      ,    
 * @author dlsm-syq
 *
 */
public class NumGenerate {

	private int size;//          
	
	private Random random = new Random();
	
	private Set<Integer> sets = new HashSet<Integer>();
	
	public NumGenerate(int size) {
		this.size = size;
		generate();
	}
	
	private void generate() {
		while(sets.size() != size){//  sets       ,     
			int i = random.nextInt(this.size * 2);
			if(!sets.contains(i)){
				sets.add(i);
			}
		}
	}
	
	//      ,  5 ,     5   
	public int[][] getDoubleArrray(){
		int col = this.size / 5;//      
		int[][] array = new int[5][col];
		for (Iterator<Integer> iterator = sets.iterator(); iterator.hasNext();) {
			for (int i = 0; i < 5; i++) {
				for (int j = 0; j < col; j++) {
					array[i][j] = iterator.next();
				}
			}
		}
		return array;
	}
}

5つのスレッドを開き、2 D配列の数値を検索します.1つのスレッドが見つかったら、すべてのスレッドを中断します.スレッドに数字が見つからない場合は長時間スリープし、5つのスレッドに数字が見つからない場合はすべてのスレッドを中断します.
9.スレッドファクトリクラス
ファクトリモードを使用してスレッドを生産し、スレッドの管理を容易にします.主な使い方は、ThreadFactoryインタフェースを実装し、public Thread newThread(Runnable r)メソッドを複写すれば簡単です.
public class MyThreadFactory implements ThreadFactory{
	
	private String name;
	private int count = 0;
	
	public MyThreadFactory(String name) {
		this.name = name;
	}
	
	
	@Override
	public Thread newThread(Runnable r) {
		Thread thread = new Thread(r,this.name + "prudct:" + count);
		this.count ++;
		return thread;
	}

}
public class JavaCurrent {

	public static void main(String[] args) {
		MyThreadFactory mtf = new MyThreadFactory("factory");
		for (int i = 0; i < 4; i++) {
			Thread t = mtf.newThread(new Task());
			t.start();
		}
	}
}


class Task implements Runnable{

	@Override
	public void run() {
		System.out.println(this.toString());
	}
	
}

以上の文章はすべて自分の本の中の知識に対する理解で、手の小さい例を練習して、多くの間違いの地方があるかもしれなくて、またみんなが多く含んで指導することを望んで、ありがとうございます.