Callable和线程池
Callable接口jdk5+
Callable<V>
接口用于表示可以在单独线程中执行并返回结果的任务。
Callable 与 Runnable 类似,但有以下几个区别:
返回结果:Callable 的
call()
方法可以返回结果,而 Runnable 的 run() 方法返回 void;抛出异常:Callable 的
call()
方法可以通过 throws 抛出异常,而 Runnable 的 run() 方法只能 try..catch..;
缺点
- 在主线程中调用
get()
方法获取 call() 方法的返回值时,会堵塞主线程。
java
public static void main(String[] args) {
MyThread myThread = new MyThread();
FutureTask<Integer> futureTask = new FutureTask<>(myThread);
Thread thread = new Thread(futureTask);
thread.start();
try {
//调用该方法时,主线程是阻塞状态,也就是 myThread 线程执行完毕,才会执行这句
Integer res = futureTask.get();
System.out.println("总和是:" + res);
} catch (Exception e) {
e.printStackTrace();
}
}
class MyThread implements Callable<Integer> {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println(i);
sum += i;
}
}
return sum;
}
}
java
public static void main(String[] args) {
//提供指定线程数量的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
//实现 Callable 接口时,使用 submit() 调用
service.submit(new MyThread());
//关闭线程池
service.shutdown();
}
线程池JUC深入讲解
线程池的优势:
- 提高了程序执行的效率:因为线程池已经提前创建好了;
- 提高了资源复用率:因为执行完的线程并没有立即销毁,而是可以继续执行其他的任务;
- 可以设置线程的相关参数:对线程池中的使用进行管理;
java
public static void main(String[] args) {
//提供指定线程数量的线程池
ExecutorService service = Executors.newFixedThreadPool(10);
ThreadPoolExecutor service1 = (ThreadPoolExecutor) service;
//设置线程池中线程数的上限
service1.setMaximumPoolSize(50);
//实现 Runnable 接口,使用 execute() 方法调用
service.execute(new PrintfEven());
service.execute(new PrintfOdd());
//关闭连接池
service.shutdown();
}
class PrintfEven implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
if (i % 2 == 0) {
System.out.println("线程一:" + i);
}
}
}
}
class PrintfOdd implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
if (i % 2 != 0) {
System.out.println("线程二:" + i);
}
}
}
}