import java.util.ArrayList;
import java.util.List;
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;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class CallableDemo implements Callable<String> {
@Override
public String call() throws Exception {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName());
return "hello CallableDemo";
}
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
System.out.println(Thread.currentThread().getName());
// 分步骤调用
/*CallableDemo callableDemo = new CallableDemo();
FutureTask<String> future = new FutureTask<>(callableDemo);
// 不能调用FutureTask的run方法,因为它类似于调用Thread.run方法,只是普通调用,不会启用多线程
new Thread(future).start();
String s = future.get();
System.out.println(s);*/
// 匿名类
/*FutureTask<String> f = new FutureTask<>(() -> {
System.out.println("callable匿名类方法体");
System.out.println(Thread.currentThread().getName());
return "callable匿名类用法";
});
new Thread(f).start();
System.out.println(f.get());*/
// 线程池submit(Callable)
/*List<Future<String>> futureList = new ArrayList<>();
// ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
// TODO Auto-generated method stub
return new Thread(r, "myThreadName");
}
});
for (int i = 1; i <= 3; i++) {
Future<String> submit = fixedThreadPool.submit(() -> {
System.out.println(Thread.currentThread().getName());
Thread.sleep(3000);
return "b";
});
futureList.add(submit);
}
for (int i = 0; i < futureList.size(); i++) {
Future<String> rs = futureList.get(i);
System.out.println(rs.get());
}
fixedThreadPool.shutdown();*/
// 线程池submit(FutureTask)
List<Future<String>> futureList = new ArrayList<>();
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5, new ThreadFactory() {
@Override
public Thread newThread(Runnable r) {
// TODO Auto-generated method stub
return new Thread(r, "myThreadName");
}
});
for (int i = 1; i <= 5; i++) {
// 第一种写法,直接用了CallableDemo
CallableDemo callableDemo = new CallableDemo();
FutureTask<String> future = new FutureTask<>(callableDemo);
fixedThreadPool.submit(future);
futureList.add(future);
// 第二种写法,没用CallableDemo,用的匿名类方式
/*FutureTask<String> future = new FutureTask<>(() -> {
// System.out.println("callable匿名类方法体");
System.out.println("线程名称=" + Thread.currentThread().getName());
Thread.sleep(10000);
return "a";
});
// 线程池执行多线程
fixedThreadPool.submit(future);
// 不用线程池执行
// new Thread(future, "线程" + (i+1)).start();
futureList.add(future);*/
}
System.out.println(futureList.size());
for (int i = 0; i < futureList.size(); i++) {
Future<String> rs = futureList.get(i);
// get()会无休止的等下去,一直阻塞线程,
// 所以最好加时间和单位(超时会抛异常TimeoutException),防止无休止的阻塞主线程
// System.out.println(rs.get());
// 5秒 < 线程的10秒,所以会TimeoutException
// System.out.println(rs.get(5, TimeUnit.SECONDS));
// 11秒 > 线程的10秒,所以会一直阻塞,知道最后一个get到结果,才会继续主线程
System.out.println(rs.get(11, TimeUnit.SECONDS));
}
fixedThreadPool.shutdown();
// Future的get()方法会阻塞线程,如果上面没有遍历futureList或者只注释掉rs.get,那么会先
// 输出 “走到底了”,然后等10秒钟结束主线程
System.out.println("走到底了");
}
}
Callable小例子
最新推荐文章于 2024-04-23 18:52:22 发布