前言
如果我们使用线程的时候就去创建一个线程,这样虽然很方便,但也会带来一个问题。
频繁的创建、销毁线程会大大降低系统的效率,因为频繁的创建线程和销毁线程需要时间。
java中的解决方法就是使用线程池来达到这样的效果。
那么什么是线程池呢?
线程池的概念
线程池:其实就是一个容纳多个线程的容器,其中的线程可以反复使用,省去了频繁创建线程对象的操作,无需反复创建线程而消耗过多资源。
理解:装线程的池子,线程池中装的是线程,它是一种类似于ArrayList集合这样的容器的容器。就是个装东西的,只不过装的是线程。
线程池就是一个装线程的容器。
这张图片展示了线程的工作流程。
合理使用线程池的好处
- 降低资源消耗,减少了创建和销毁线程的次数,每个工作线程都可以被重复使用,可执行多个任务。
- 提高响应速度,当任务到达时,任务可以不需要等到线程创建就能立即执行。
- 3、提高线程的可管理性,可以根据系统的承受能力,调整线程池中工作的线程的数目,每个线程需要大约1M的内存)
线程池的代码实现
java.util.concurrent.Executors:线程池的工厂类,用来生成线程池
Excecutors类中的静态方法:
public static ExecutorService newFixedThreadPool(int nThreads)
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
参数:创建线程池汇总包含的线程数量
返回值:
ExecutorService接口,返回的是ExecutorService接口的实现类对象,我们可以使用ExecutorService接口接收(面向接口编程)
java.util.concurent.ExecutorService:线程池接口
用来从线程池中获取线程,调用start()方法,执行线程任务。
submit(Runnable task) 提交一个Runnable任务用于执行。
关闭/销毁线程池的方法
void shutdown()(不推荐使用)
线程池的使用步骤
1、使用线程池工厂类Executors里边提供的静态方法newFixedThreadPool生产一个指定线程数量的线程池。
2、创建一个类,实现Runnable接口,重写run()方法,设置线程任务。
3、调用ExecutorService中的方法submit(),传递线程任务(Runnable的实现类对象),开启线程,执行run()方法
4、调用ExecutorService中的方法shutdown()销毁线程池(不建议执行)
举例:
public class ExecutorServiceTest {
public static void main(String[] args) {
/*
java.util.concurrent.Executors:这个类是一个工厂类,用于生产线程池
java.util.concurrent.ExecutorService:这个是线程池接口,用它来接收它的实现类的线程池对象
*/
ExecutorService es = Executors.newFixedThreadPool(4);//获取一个线程池,
es.submit(new RunnableImpl());//提交线程任务,任务是Runnable接口的实现类对象
es.submit(new RunnableImpl());//这里提交了第二个任务
es.submit(new RunnableImpl());
}
}
public class RunnableImpl implements Runnable {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()+"-->"+i);
}
}
}