Javaに戻り値があるスレッド、スレッドプールの初期使用


一概要
JDK 1.5以前のスレッドには戻り値がなく(Thread,Runnable)、Callableというインタフェースはその後に現れた新しい特性で、使い方はRunnableと似ていますが、違いは戻り値があることです.そこでCallableというクラスやスレッドプールに関する内容をテストするために、前の記事のコードを小幅に修正して書いてみました
二スレッドプールの簡単な使用手順について
1 スレッドクラスの定義(1)extends Thread (2)implements Runnable (3)implements Callable<> 
2 ExecutorServiceスレッドプールを作成します.たとえば、ExecutorService pool=Executors.newCachedThreadPool()と書きます.これはキャッシュプールを構築します.一般的によく使われるのは、(1)newFixedThreadPool() (2)ScheduledThreadPool() (3)SingleThreadExecutor()
3 スレッドプールを呼び出して操作
//タスクを実行し、Futureオブジェクトを取得する 
Future> future = pool.submit(myThread);
//Futureオブジェクトからタスクの戻り値を取得する
future.get();
トリプルテストコード
package thread;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class Test2 {

	public static void main(String[] args) {
		long millis1 = System.currentTimeMillis();
		String fileName = "C:\\Users\\Administrator\\Desktop\\  2.txt";
		int threadNum = 5;  //        
		List<String> list = new ArrayList<String>();
		
		//         
		ExecutorService pool = Executors.newCachedThreadPool();
		for (int i = 0; i < threadNum; i++) {
			Callable<List<String>> myThread = new MyThread2("  " + i, i, threadNum);
			Future<List<String>> future = pool.submit(myThread);
			try {
				list.addAll(future.get());
			} catch (InterruptedException e) {
				e.printStackTrace();
			} catch (ExecutionException e) {
				e.printStackTrace();
			}
		}
		pool.shutdown();  //     ,           
		
		Iterator<String> iterator = list.iterator();
		try {
			BufferedWriter writer = new BufferedWriter(new FileWriter(new File(fileName)));
			while(iterator.hasNext()){
				writer.write(iterator.next());
				writer.newLine();
				writer.flush();
			}
			writer.close();
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		long millis2 = System.currentTimeMillis();
		System.out.println(millis2 - millis1);  //  170-177ms
	}

}

/**
 *      (  )
 * */
class MyThread2 implements Callable<List<String>>{
	private String name; //      
	private int i; //      
	private int threadNum; //          

	public MyThread2(String name, int i, int threadNum) {
		this.name = name;
		this.i = i;
		this.threadNum = threadNum;
	}

	public List<String> call() throws Exception {
		MyPrint2 myPrint2 = new MyPrint2();
		return myPrint2.print(name, i, threadNum);
	}
	

}

/**
 *        
 * */
class MyPrint2 {

	public List<String> print(String name, int x, int threadNum) {
		List<String> list = new ArrayList<String>();

		for (int i = x; i <= 10000; i = i + threadNum) {
//			System.out.println(name + ": " + i + "----------------------------------          ");
			list.add(name + ": " + i + "----------------------------------          ");
		}		
		return list;
	}

}

注:この書き方は手順が多いので、ここでは逆にシングルスレッドよりも少し遅いO(∩∩)O~