Java 创建线程的三种方式

创建线程

  • 继承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
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

    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;
}
}

猜你喜欢

转载自www.cnblogs.com/pamCoding/p/9479808.html