javaマルチスレッド学習-----初めてスレッド池に入る
7061 ワード
もっと読む
スレッドを使う
最近のプロジェクトはコードの最適化をしています.業務機能があります.大体20台の内線が交換台にファイルを送ります.交換機はファイルを受け取った後、内線にデータの処理状況をフィードバックします.
この時はスケジュールを使って、交換台に届いたメッセージを調べたいです.処理後、各内線に送ります.待ち時間を避けるために、マルチスレッドを使って、スレッドを使って管理します.
スレッドを作成
資料を検索した後、JDK 1.5のjava.util.co ncurrentパッケージを用いてスレッド池を作成し、この例では固定スレッド数を再利用できるスレッド池を使用して、コードは以下の通りである.
タスク実行結果を取得
そして、FutureTaskクラスを使ってタスク実行結果を取得し、タスクタイムアウト時間を設定できます.コードは以下の通りです.
パラメータmayInterruptIfRunning-このタスクを実行するスレッドを中断すべきなら、trueです.さもなければ実行中のタスクの実行が完了します.コードは以下の通りです.
タスクフラグ
また、実行中のジョブを取得するために、各タスクに対してマークを付けて、mapセットに保存します.コードは以下の通りです.
私たちはまた、マークによって実行中のタスクを中断することができます.コードは以下の通りです.
参考資料:http://blog.csdn.net/hemingwang0902/article/details/4557304
http://westyi.iteye.com/blog/714935
寄り添って歩幅も千里もない
スレッドを使う
最近のプロジェクトはコードの最適化をしています.業務機能があります.大体20台の内線が交換台にファイルを送ります.交換機はファイルを受け取った後、内線にデータの処理状況をフィードバックします.
この時はスケジュールを使って、交換台に届いたメッセージを調べたいです.処理後、各内線に送ります.待ち時間を避けるために、マルチスレッドを使って、スレッドを使って管理します.
スレッドを作成
資料を検索した後、JDK 1.5のjava.util.co ncurrentパッケージを用いてスレッド池を作成し、この例では固定スレッド数を再利用できるスレッド池を使用して、コードは以下の通りである.
private static int maxThreads = 20; //
private static ExecutorService e = Executors.newFixedThreadPool(maxThreads); //
タスク実行結果を取得
そして、FutureTaskクラスを使ってタスク実行結果を取得し、タスクタイムアウト時間を設定できます.コードは以下の通りです.
FutureTask ft = new FutureTask(thread,true);
e.execute(ft);
Boolean fTaskResult = ft.get(); // , ,
//Boolean fTaskResult = ft.get(fTimeout, TimeUnit.SECONDS); // , , , , TimeoutException
もしタスクがタイムアウトしたら、私たちはFutureTaskクラスのcancelを呼び出すことができます.パラメータmayInterruptIfRunning-このタスクを実行するスレッドを中断すべきなら、trueです.さもなければ実行中のタスクの実行が完了します.コードは以下の通りです.
catch (TimeoutException e) {
System.out.println(" , ");
ft.cancel(true);
}
しかし、このように問題があるのは、FutureTaskオブジェクトのget()メソッドを呼び出すと、タスクが完了するまでスレッドがブロックされ、他のスレッドの実行が停止され、オンライン検索で結果がない場合は、スレッドをもう一つ開けて、FutureTaskオブジェクトのget()を実行する方法である.コードは以下の通りである. /**
*
* @param t
*/
public static void beginTask(Thread t){
e.execute(t);
}
/**
*
* @param key
* @param t
*/
public static void beginTask(String key,Thread thread){
final String fKey = key;
final FutureTask ft = new FutureTask(thread,true);
runningTaskMap.put(key, ft); //
e.execute(ft);
beginTask(new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
Boolean fTaskResult = ft.get();
if(fTaskResult){
System.out.println("key :"+fKey+" ");
}
} catch (InterruptedException e) {
System.out.println(" ");
} catch (ExecutionException e) {
System.out.println(" , ");
}finally{
runningTaskMap.remove(fKey); //
}
}
});
}
タスクフラグ
また、実行中のジョブを取得するために、各タスクに対してマークを付けて、mapセットに保存します.コードは以下の通りです.
//
private static Map> runningTaskMap = Collections.synchronizedMap(new HashMap>());
スレッドプールを呼び出すたびに、mapセットに記録を保存し、呼び出しが完了したら削除します.私たちはまた、マークによって実行中のタスクを中断することができます.コードは以下の通りです.
/**
* ,
* @param key
*/
public static void intteruptTask(String key){
FutureTask ft = runningTaskMap.get(key);
ft.cancel(true);
if(ft.isDone()){
runningTaskMap.remove(key);
}
}
最後に完全なコードを添付します.package task.concurrent.threadPoor;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class FixedThreadPool {
private static int maxThreads = 20; //
private static ExecutorService e = Executors.newFixedThreadPool(maxThreads); //
//
private static Map> runningTaskMap = Collections.synchronizedMap(new HashMap>());
/**
*
* @param t
*/
public static void beginTask(Thread t){
e.execute(t);
}
/**
*
* @param key
* @param t
*/
public static void beginTask(String key,Thread thread){
final String fKey = key;
final FutureTask ft = new FutureTask(thread,true);
runningTaskMap.put(key, ft); //
e.execute(ft);
beginTask(new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
Boolean fTaskResult = ft.get();
if(fTaskResult){
System.out.println("key :"+fKey+" ");
}
} catch (InterruptedException e) {
System.out.println(" ");
} catch (ExecutionException e) {
System.out.println(" , ");
}finally{
runningTaskMap.remove(fKey); //
}
}
});
}
/**
*
* @param key
* @param thread
* @param timeout
*/
public static void beginTask(String key, Thread thread, int timeout) {
final String fKey = key;
final int fTimeout = timeout;
final FutureTask ft = new FutureTask(thread,true);
runningTaskMap.put(key, ft); //
e.execute(ft);
beginTask(new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
try {
Boolean fTaskResult = ft.get(fTimeout, TimeUnit.SECONDS);
if(fTaskResult){
System.out.println("key :"+fKey+" ");
}
} catch (InterruptedException e) {
System.out.println(" ");
} catch (ExecutionException e) {
System.out.println(" , ");
} catch (TimeoutException e) {
System.out.println(" , ");
ft.cancel(true);
}finally{
runningTaskMap.remove(fKey); //
}
}
});
}
/**
* ,
* @param key
*/
public static void intteruptTask(String key){
FutureTask ft = runningTaskMap.get(key);
ft.cancel(true);
if(ft.isDone()){
runningTaskMap.remove(key);
}
}
/**
*
*/
public static void shutDownPool(){
e.shutdown();
}
}
まとめ:呼び出しとテストコードは貼り付けません.スレッドの池コードを書くのは初めてですので、足りないところがたくさんあります.参考資料:http://blog.csdn.net/hemingwang0902/article/details/4557304
http://westyi.iteye.com/blog/714935
寄り添って歩幅も千里もない