创建线程
- 继承Thread
public class MyThread extends Thread{
@override
public void run(){
//do something
}
}
//调用
MyThread myThread = new MyThread();
myThread.run();
- 实现Runnable
public class MyThread implements Runnable{
@override
public void run(){
//do something
}
}
//调用
MyThread myThread = new MyThread();
new Thread(myThread).start();
//Lambda style
new Thread(()->{
//do something
return xxx;
}
).start();
-
实现Callable
这种实现方式的线程执行方式通常使用线程池的submit方法来提交任务,也可以封装为FutureTask<T>再用new Thread(FutureTask<T>).start()来启动
public class MyThread<Integer> implements Callable<Integer>{
//may have constructor
@override
public Integer call(){
//do something
return xxx;
}
}
/*******************非线程池方式*************************/
//调用
Mythread myThread = new MyThread();
FutureTask<Integer> result = new FutureTask<>(myThread);
Thread thread = new Thread(result);
thread.start();
try{
//get result
Integer res = result.get();
}catch(InterruptedException|ExecutionException e){
e.printStackTrack();
}
//Lambda style
new Thread(new FutureTask<Integer>((Callable<Integer>)()->{
//do something
return xxx;
})
).start();
/**********************线程池方式**********************/
ExecutorService executor = Executors.newCachedThreadPool();
Future<Integer> result = executor.submit(new MyThread());
Runnable和Callable实现的区别
- 前者(实现Runnable的任务)不能有返回值,而后者(实现Callable的任务)可以有返回值
- 前者可以直接通过new Thread(Runnable).start()来启动,而后者必须封装为FutureTask<T>再由new Thread(FutureTask<T>).start()来启动
Future
Future能够异步保留执行结果,提供下面的几种方法来管理线程和县城结果
- cancel(boolean mayInterruptIfRunning):试图取消执行的任务,参数为true时直接中断正在执行的任务,否则直到当前任务执行完成,成功取消后返回true,否则返回false
- isCancel():判断任务是否在正常执行完前被取消的,如果是则返回true
- isDone():判断任务是否已完成
- get():等待计算结果的返回,如果计算被取消了则抛出
- get(long timeout,TimeUtil unit):设定计算结果的返回时间,如果在规定时间内没有返回计算结果则抛出TimeOutException
Future+Callable实现多线程计算实例
代码来源:https://www.cnblogs.com/MOBIN/p/6185387.html
public class FileSearchTask {
public static void main(String[] args) throws ExecutionException, InterruptedException {
String path = args[0];
String keyword = args[1];
int c = 0;
File[] files = new File(path).listFiles();
ArrayList<Future<Integer>> rs = new ArrayList<>();
for(File file: files){ //每个文件启动一个task去查找
MatchCount count = new MatchCount();
count.file = file;
count.keyword = keyword;
FutureTask<Integer> task = new FutureTask(count);
rs.add(task); //将任务返回的结果添加到集合中
Thread thread = new Thread(task);
thread.start();
}
for(Future<Integer> f: rs){
c += f.get(); //迭代返回结果并累加
}
System.out.println("包含关键字的总文件数为:" + c);
}
}
public class MatchCount implements Callable<Integer>{
public File file;
public String keyword;
private Integer count = 0;
public Integer call() throws Exception { //call封装线程所需做的任务
if(search(file))
count ++;
return count;
}
public boolean search(File file){
boolean founded = false;
try(Scanner scanner = new Scanner(new FileInputStream(file))){
while(!founded && scanner.hasNextLine()){
if (scanner.nextLine().contains(keyword))
founded = true;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return founded;
}
}
网友评论