首先,什么是线程池?
线程池是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程的操作,节省了反复创建线程消耗的资源。
为什么要创建线程池?
在实际应用中,创建和销毁线程消耗的资源都非常大,有时候会比处理实际用户请求消耗的时间和资源还要多,而系统有可能就会因为消耗内存过度或者切换频繁而资源耗尽,为了减少这种情况的发生,我们使用线程池来限制线程的数量,更好的利用线程,减少频繁的创建和销毁。
Java线程池的顶级接口是Executor,不过真正的接口是ExecutorService,其默认实现是ThreadPoolExecutor。
Executors是线程池创建工厂类。
其提供四种线程池:
1.newCashedThreadPool
2.newFixedThreadPool
3.newScheduledThreadPool
4.newSingleThreadPool
重点记一下ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
重点参数:
1.corePoolSize:线程池的核心线程,一般会在线程中一直存活。
2.maximumPoolSize:线程池所能容纳的最大线程数,活动的线程数超过后,后续的线程会阻塞。
3.keepAliveTime:控制线程闲置的时长,超过则终止该线程。一般用于非核心线程,当allowCoreThreadTimeOut()设置为true时,同样作用于核心线程。
使用线程池方式——实例1
Runnable接口
public class Test implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "start");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}// 线程使用完毕归还线程池
System.out.println(Thread.currentThread().getName() + "finished");
}
}
public class TestDemo {
public static void main(String[] args) {
// 创建线程池对象(包含两个线程)
ExecutorService executorService = Executors.newFixedThreadPool(2);
Test runnable = new Test();
// 不使用线程池启动线程的方式
// Thread thread = new Thread(runnable);
// thread.start();
// 从线程池中获取线程对象,然后调用Test的run()
executorService.submit(runnable);
executorService.submit(runnable);
// submit方法调用结束后,程序并不终止,
// 因为线程池控制了线程的关闭。将使用完的线程又归还到了线程池
// 手动关闭线程池。一般不使用,我们使用线程池的目的就是为了复用线程
executorService.shutdown();
}
}
运行结果
pool-1-thread-1start
pool-1-thread-2start
pool-1-thread-2finished
pool-1-thread-1finished
实例2
Callable接口
public class Test implements Callable {
@Override
public Object call() throws Exception {
System.out.println(Thread.currentThread().getName() + "start");
Thread.sleep(1000);
// 线程使用完毕归还线程池
System.out.println(Thread.currentThread().getName() + "finished");
return Thread.currentThread().getName();
}
}
public class TestDemo {
@Test
public void test() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
Test callable = new Test();
// 从线程池中获取线程
Future<String> submit = executorService.submit(callable);
String result = submit.get();
System.out.println("线程名字" + result);
// 关闭线程池
executorService.shutdown();
}
}