线程池:
其实就是一个容纳多个线程的容器,其中的线程可以反复的使用,省去了频繁创建和销毁过程对象的操作,无需反复创建线程面消耗过多资源。
为什么要用线程池:
合理利用线程池能够带来三个好处
- 降低资源消耗
减少了创建和销毁线程的次数,每个工作线程都可以被重复利用。可执行多个任务。 - 提高响应速度
不需要频繁的创建线程。如果有线程可以直接用,不会出现系统僵死。 - 提高线程的可管理性
线程池可以约束系统最多只能有多少个线程,不会因为线程过多而死机。
创建线程池
线程池在Java中的代表类:Executorservice (接口)。
Java在Executors类下提供了一个静态方法得到一个线程池的对象:
public static Executorservice newFixedThreadPool (int nThreads)
Executorservice提交线程任务对象执行的方法:
- Future<?> submit (Runnable task):提交一个Runnable的任务对象给线程池执行。
- Future<?> submit (Callable task):提交一个Callable的任务对象给线程池执行。
一、Runnable线程池
public class Demo1 {
public static void main(String[] args) {
//创建一个线程池,指定线程固定数量为3
ExecutorService pools = Executors.newFixedThreadPool(3);
//添加线程任务让线程池处理
Runnable target = new MyRunnable();
pools.submit(target);//第1次提交任务,此时第1个线程创建
pools.submit(target);//第2次提交任务,此时第2个线程创建
pools.submit(target);//第3次提交任务,此时第3个线程创建
pools.submit(target);//第4次提交任务,此时复用之前的线程
//pools.shutdown();//等待任务执行完毕以后才会关闭线程池
pools.shutdownNow();//立即关闭线程池代码,无论任务是否执行完毕
}
}
class MyRunnable implements Runnable{
@Override
public void run() {
for (int i =0;i <10 ;i++){
System.out.println(Thread.currentThread().getName()+"=>"+i);
}
}
}
二、Callable线程池
public class Demo2 {
public static void main(String[] args) {
//创建一个线程池,指定线程的固定数量是3
ExecutorService pools = Executors.newFixedThreadPool(3);
//提交Callable的任务对象后返回一个未来任务对象
Future<String> t1 = pools.submit(new MyCallable(100));
Future<String> t2 = pools.submit(new MyCallable(200));
Future<String> t3 = pools.submit(new MyCallable(300));
Future<String> t4 = pools.submit(new MyCallable(400));
//获取线程池执行的任务结果
try {
String rs1 = t1.get();
String rs2 = t2.get();
String rs3 = t3.get();
String rs4 = t4.get();
System.out.println(rs1);
System.out.println(rs2);
System.out.println(rs3);
System.out.println(rs4);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class MyCallable implements Callable<String>{
//需求:使用线程池计算1-100,1-200,1-300的和返回
private int n;
public MyCallable(int n){
this.n = n;
}
@Override
public String call() throws Exception {
int sum = 0;
for (int i =1; i<=n ;i++) {
sum += i;
}
return Thread.currentThread().getName()+"结果是"+sum;
}
}