引入:
创建执行线程的方式有四种:
1.继承Thread类
2.实现Runnable接口
3.实现Callable接口
4.线程池
前两种用的最多,今天就来演示一下后两种方法创建线程,即实现Callable接口和使用线程池。
1、实现Callable接口:
Callable是JUC中的一个接口,相较于实现Runnable接口的方式,其方法可以有返回值,并且可以抛出异常。另外,使用Callable接口需要FutureTask实现类的支持,用于接收运算结果。FutureTask是Future接口的实现类。
实际操作:
package com.tongtong.app7;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class TestCallable {
public static void main(String[] args) {
ThreadDemo td = new ThreadDemo();
//1.使用Callable,需要FutureTask实现类的支持,用于接收运算结果
FutureTask<Integer> result = new FutureTask<>(td);
new Thread(result).start();
//2.接收线程运算后的结果
try {
Integer sum = result.get();
System.out.println(sum);
System.out.println("---------------------");
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
class ThreadDemo implements Callable<Integer>{
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i = 0;i <= 100000; i++){
sum += i;
}
return sum;
}
}
2、线程池
线程池:提供一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。
二、线程池的体系结构:
java.util.concurrent.Executor:负责线程的使用与调度的根接口
|--ExecutorService 子接口:线程池的主要接口(重要)
|--ThreadPoolExecutor 线程池的实现类
|--ScheduledExecutorService:子接口:负责线程的调度
|--ScheduledThreadPoolExecutor :继承ThreadPoolExecutor,实现ScheduledExecutorService
三、工具类 : Executors
ExecutorService newFixedThreadPool() : 创建固定大小的线程池
ExecutorService newCachedThreadPool() : 缓存线程池,线程池的数量不固定,可以根据需求自动的更改数量
ExecutorService newSingleThreadExecutor() : 创建单个线程池,线程池中只有一个线程
ScheduledExecutorService newScheduledThreadPool() : 创建固定大小的线程,可以延迟或定时的执行任务
实际操作:
1、创建固定大小的线程池(ExecutorService newFixedThreadPool())
package com.tongtong.app8;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class TestThreadPool {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1、创建固定大小的线程池
ExecutorService pool = Executors.newFixedThreadPool(5);
List<Future<Integer>> list = new ArrayList<>();
for(int i = 0;i < 10; i++){ //分配10个任务
//接收返回值
Future<Integer> future = pool.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i =0;i <= 100;i++){
sum += i;
}
return sum;
}
});
list.add(future);
}
//关闭线程池
pool.shutdown();
for(Future<Integer> future : list){
System.out.println(future.get());
}
}
}
2、创建缓存线程池(ExecutorService newCachedThreadPool())
package com.tongtong.app8;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class TestThreadPool {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1、创建缓存的线程池
ExecutorService pool = Executors.newCachedThreadPool(5);
List<Future<Integer>> list = new ArrayList<>();
for(int i = 0;i < 10; i++){ //分配10个任务
//接收返回值
Future<Integer> future = pool.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i =0;i <= 100;i++){
sum += i;
}
return sum;
}
});
list.add(future);
}
//关闭线程池
pool.shutdown();
for(Future<Integer> future : list){
System.out.println(future.get());
}
}
}
3、创建单个线程的线程池(ExecutorService newSingleThreadExecutor())
package com.tongtong.app8;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
public class TestThreadPool {
public static void main(String[] args) throws ExecutionException, InterruptedException {
//1、创建线程池
ExecutorService pool = Executors.newSingleThreadExecutor();
List<Future<Integer>> list = new ArrayList<>();
for(int i = 0;i < 10; i++){
Future<Integer> future = pool.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for(int i =0;i <= 100;i++){
sum += i;
}
return sum;
}
});
list.add(future);
}
pool.shutdown();
for(Future<Integer> future : list){
System.out.println(future.get());
}
}
}
4、创建固定大小的线程池,可以延迟或定时的执行任务(ScheduledExecutorService newScheduledThreadPool())
package com.tongtong.app8;
import java.util.Random;
import java.util.concurrent.*;
public class TestScheduledThreadPool {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);
for(int i = 0;i < 5; i++){
Future<Integer> result = pool.schedule(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(100);
System.out.println(Thread.currentThread().getName() + " : " + num);
return num;
}
},1, TimeUnit.SECONDS); //定时执行
System.out.println(result.get());
}
pool.shutdown();
}
}