构建一个新的线程是有一定代价的。如果程序需要创建大量生命周期很短的线程,应该使用线程池。
执行器类有许多静态工厂方法构建线程池。
方法描述newCachedThreadPool必要时创建新线程;空闲线程会被保留60秒newFixedThreadPool该池包含固定数量的线程;空闲线程会一直被保留newSingleThreadExecutor只有一个线程的“池”,该线程顺序执行每一个提交的任务newScheduledThreadPool用于预定执行而构建的固定线程池,替代java.util.TimernewSingleThreadScheduledExecutor用于预定执行而构建的单线程池上述表中前三个方法返回实现了ExecutorService接口的ThreadPoolExecutor对象。 使用submit()方法提交Runnable对象或Callable对象。 当用完一个线程池的时候,调用shutdown()。
例子,使用线程池查询文件
import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.concurrent.*; public class SearchFile { public static void main(String[] args) throws ExecutionException, InterruptedException { File directory = new File("D:\\"); String filename = "确认.pdf"; ExecutorService pool = Executors.newCachedThreadPool(); SearchFileThread search = new SearchFileThread(directory, filename, pool); Future<List<String>> futures = pool.submit(search); List<String> results = futures.get(); for (String str : results) { System.out.println(str); } pool.shutdown(); int largestPoolSize = ((ThreadPoolExecutor)pool).getLargestPoolSize(); System.out.println("线程池最大的长度:" + largestPoolSize); } static class SearchFileThread implements Callable<List<String>> { private File directory; private String filename; private ExecutorService pool; public SearchFileThread(File directory, String filename, ExecutorService pool) { this.directory = directory; this.filename = filename; this.pool = pool; } @Override public List<String> call() throws Exception { List<String> resultList = new ArrayList<>(); File[] files = directory.listFiles(); List<Future<List<String>>> results = new ArrayList<>(); if (files != null) { for (File file : files) { if (file.isDirectory()) { SearchFileThread thread = new SearchFileThread(file, filename, pool); Future<List<String>> result = pool.submit(thread); results.add(result); } else { // System.out.println(file.getAbsolutePath()); if (file.getName().equals(filename)) { resultList.add(file.getAbsolutePath()); } } } } for (Future<List<String>> future : results) { resultList.addAll(future.get()); } return resultList; } } }上述表中后两个方法返回实现了ScheduledExecutorService接口的对象。 例子
import java.util.Date; import java.util.concurrent.*; public class ScheduledExecutorTest { public static void main(String[] args) { ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2); Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { String time = new Date().toString(); System.out.println(time); return time; } }; // 预定在指定时间之后执行任务 ScheduledFuture<String> future = scheduledExecutorService.schedule(callable, 1000, TimeUnit.MILLISECONDS); Runnable runnable1 = new Runnable() { @Override public void run() { String time = new Date().toString(); System.out.println("scheduleAtFixedRate() " + time); } }; //public ScheduledFuture<?> scheduleAtFixedRate(Runnable command,long initialDelay,long period,TimeUnit unit); // 周期长度是period // 多少秒之后再执行, 是从上一个任务开始时开始计算 ScheduledFuture<?> future1 = scheduledExecutorService.scheduleAtFixedRate(runnable1, 0, 1, TimeUnit.MINUTES); Runnable runnable2 = new Runnable() { @Override public void run() { String time = new Date().toString(); System.out.println("scheduleWithFixedDelay() " + time); } }; // public ScheduledFuture<?> scheduleWithFixedDelay(Runnable command,long initialDelay,long delay,TimeUnit unit); // 两个周期之间有delay长度的时延 // 多少秒之后再执行, 是从上一个任务结束时开始计算 ScheduledFuture<?> future2 = scheduledExecutorService.scheduleWithFixedDelay(runnable2, 0, 1, TimeUnit.MINUTES); } }