java线程池介绍与使用
在同等数量级的操作下,使用线程池的效率要远远高于单线程。线程池可以降低创建线程带来的开销。而线程池中的线程结束后进行的是回收操作而不真的将线程销毁。而在这个过程过,线程池带来的内存消耗肯定会大于单线程。在使用线程池的时候要慎重这个问题。下面进行两个方法,分别来测试下。
import java.util.LinkedList; import java.util.List; import java.util.Random; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadpoolDemo1 { static void useThreadPool(int count) { //定义存储集合 final List<Integer> list = new LinkedList<Integer>(); long startTime = System.currentTimeMillis(); ThreadPoolExecutor tpe = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(count) ); //产生随机数 final Random random = new Random(); for (int i=0; i < count; i++) { tpe.execute(new Runnable() { @Override public void run() { list.add(random.nextInt()); } }); } tpe.shutdown(); try { tpe.awaitTermination(1, TimeUnit.DAYS); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(System.currentTimeMillis() - startTime); System.out.println(list.size()); } static void useOneThread(int count){ final List<Integer> list = new LinkedList<Integer>(); long startTime = System.currentTimeMillis(); //产生随机数 final Random random = new Random(); for (int i=0; i<count; i++) { Thread thread = new Thread(){ public void run() { list.add(random.nextInt()); } }; thread.start(); try { thread.join(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println(System.currentTimeMillis() - startTime); System.out.println(list.size()); } public static void main(String[] args) { useThreadPool(20000); useOneThread(20000); } }
在count参数为同值的时候,使用线程池会比单独创建线程的速度要快好几倍。
使用线程池的好处:
1)减少了创建和销毁线程的次数,线程可以被重复利用
2)线程池中的线程可以被程序员调节。减少系统内存的消耗。
线程池的使用:
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadPoolDemo2 { // 创建一个可重复利用的单线城池 private void testSingleThreadExecutor() { ExecutorService pool = Executors.newSingleThreadExecutor(); Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.shutdown(); } // 创建一个固定大小的线程池 private void testFixedThreadPool() { ExecutorService pool = Executors.newFixedThreadPool(3); Thread t1 = new MyThread(); Thread t2 = new MyThread(); Thread t3 = new MyThread(); pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.shutdown(); } // 创建具有定时功能的线程池 private void testScheduledThreadPoolExecutor() { ScheduledThreadPoolExecutor poolExecutor = new ScheduledThreadPoolExecutor(1); poolExecutor.scheduleAtFixedRate(new Runnable() { // 每隔一段时间就触发异常 @Override public void run() { // throw new RuntimeException(); System.out.println("================"); } }, 1000, 5000, TimeUnit.MILLISECONDS); poolExecutor.scheduleAtFixedRate(new Runnable() { // 每隔一段时间打印系统时间,证明两者是互不影响的 @Override public void run() { System.out.println(System.currentTimeMillis()); } }, 1000, 2000, TimeUnit.MILLISECONDS); } }
ThreadPoolExecutor:
创建ThreadPoolExecutor的参数:
corePoolSize: 池中所保存的线程数,包括空闲线程。
maximumPoolSize:池中允许的最大线程数。
keepAliveTime:当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
Unit:keepAliveTime 参数的时间单位。
workQueue:执行前用于保持任务的队列。此队列仅保持由 execute方法提交的 Runnable任务。
threadFactory:执行程序创建新线程时使用的工厂。
Handler:由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。