我用的是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,判断是否完成