什么是线程池:
- 为了避免系统频繁的创建和销毁线程,我们可以让创建的线程进行复用。在线程池中,总有那么几个活跃线程,当你需要使用线程时,可以从池子中随便拿一个空闲线程,当你完成工作时,并不着急关闭线程,而是将这个线程退回到池子,方便其他人使用。
java中的线程池是运用场景最多的并发框架,合理的使用线程池能够带来的3个好处:
- 第一:降低资源消耗;
- 第二:提高响应速度:
- 第三:提高线程的可管理性;
为了更好的控制多线程,JDK提供了一套Executor框架,帮助开发人员进行线程控制,其本质就是一个线程池。
如图:
- 以上成员均在java.util.concurrent包中,是JDK并发包的核心类。其中ThreadPoolExecutor表示一个线程池。Executors类扮演着线程池工厂的角色,通过Executors可以取得一个拥有特定功能的线程池。
ThreadPoolExecutor类实现Executor接口,因此通过这个接口,任何Runnable的对象都可以被ThreadPoolExecutor线程池调度。
Executor框架提供了各种类型的线程池,以下有四种常用的工厂方法:
- newFixedThreadPool()方法:该方法返回一个固定线程数量的线程池。它适用于负载比较重的服务器。
- newSingleThreadExecutor()方法:该方法返回一个只有一个线程的线程池。适用于需要保证顺序地执行各个任务,并且在任意时间点,不会有多个线程是活动的应用场景。
- newCachedThreadPool()方法:该方法返回一个可根据实际情况调整线程数量的线程池。适用于执行很多的短期异步任务的小程序,或是负载较轻的服务器。
- newSingleThreadScheduledExecutor()方法:该方法返回一个ScheduledExecutorService对象,线程池大小为1.适用于需要单个后台线程执行周期任务,同时保证顺序地执行各个任务的应用场景。
线程池的使用:
- 通过ThreadPoolExecutor来创建一个线程池;
- 可以使用两个方法向线程池提交任务:execute()和submit();
execute()方法用于提交不需要返回值的任务;
submit()方法用于提交需要返回值的任务。 - 可以通过线程池的shutdown或shutdownNow方法来关闭线程池。
shutdownNow尝试停止正在执行或暂停任务的线程;
shutdown只是将线程池的状态设置为SHUTDOWN状态,然后中断所有没有正在执行任务的线程。
以下通过一段代码来展示线程池的应用:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolTest {
public static void main(String[] args) {
ExecutorService threadPool = Executors.newFixedThreadPool(3);
for(int i=1;i<=10;i++) {
final int task = i;
threadPool.execute(new Runnable() {
@Override
public void run() {
for(int j=1;j<=10;j++) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"loop of" +j +"for task of"+ task);
}
}
});
}
System.out.println("game over");
threadPool.shutdown();
}
}
以上就是一个简单的小实例,非常适合新手学习线程池,其实线程池的实例还有好多,想多了解的可以在网上找到一大堆的资料以及源码,这里菲菲同学就不举例了,(因为我有好多点都不太懂呢,学习完全处于懵懂状态)我知道现在我写的东西特别的肤浅,如果大神们看到觉得特别幼稚的话,千万不要打击我哦。我会一步一步改进这些东西的。