我用的是Callable(譯有返回值的)方式。因爲它有返回值。具體應用還是直接上例子吧:
callable接口和Runnable接口
package thread.test04;
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 ThreadTestB {
public static void main(String[] args) {
ExecutorService e=Executors.newFixedThreadPool(10);
Future f1=e.submit(new MyCallableA());
Future f2=e.submit(new MyCallableA());
Future f3=e.submit(new MyCallableA());
System.out.println("--Future.get()....");
try {
System.out.println(f1.get());
System.out.println(f2.get());
System.out.println(f3.get());
} catch (InterruptedException e1) {
e1.printStackTrace();
} catch (ExecutionException e1) {
e1.printStackTrace();
}
e.shutdown();
}
}
class MyCallableA implements Callable<String>{
public String call() throws Exception {
System.out.println("開始執行Callable");
String[] ss={"zhangsan","lisi"};
long[] num=new long[2];
for(int i=0;i<1000000;i++){
num[(int)(Math.random()*2)]++;
}
if(num[0]>num[1]){
return ss[0];
}else if(num[0]<num[1]){
throw new Exception("棄權!");
}else{
return ss[1];
}
}
}
這只是一個簡單的demo,在實際應用中我還遇到一個問題:如何使得一個線程運行有結果後,關閉另一個線程。即取兩個線程,而在實際中二者的結果只能取其一的問題。在網上找了好久,發現大多是取標誌位flag,進行判斷。當然,我最後也用了這個方法。不得不說還是有一些問題的。問題就是當運行的時候,代碼很容易就跳過去,或者乾脆不運行這個判斷位代碼。所以,有時候加一個thread.sleep();也是蠻有用的。
後來才發現,這並不是運行的快的問題,而是自己程序的設計混亂。這種多線程的程序,邏輯和流程一定好設計清楚。才能避免不必要的問題。當然,在我做的測試中,裏面有一個線程用到了exe文件調用。後來就一直被一個問題困擾:當java調用exe文件的時候,即使在該線程中加入flag判斷,也沒有用,因爲java一定要等exe運行完了,纔會執行下一段代碼。所以,在java 如何調用 exe 文件 運行cmd命令這裏要尋找另一種可以從另一個線程中控制該線程的方法。而該線程又以此exe文件爲主導。所以當另一個線程需要關閉此線程的時候,直接用 String command = “taskkill /f /im process.exe”;
其中,相關命令詳解(WINDOWS TASKKILL命令用法詳解)*/f 表示強制終止 /im 表示指定的進程名稱,例如“explor.exe"
由於是初步實現,所以,bug在所難免。不懂是正常的,但是再調不出來的時候,一定不要慌,不要放棄。可以讓自己遠離電腦休息一下。然後寫寫流程圖。會發現一些前面看不到的問題。
另外還有一些callable的相關接口和原理,mark一下
Java 多線程 併發編程
Future接口,一般都是取回Callable執行的狀態用的。其中的主要方法:
cancel,取消Callable的執行,當Callable還沒有完成時
get,獲得Callable的返回值
isCanceled,判斷是否取消了 isDone,判斷是否完成