1. 创建线程池的方法之三:
//对于每个任务,如果有空闲的线程可用,立即让他执行任务,
//没有空闲的线程则创建一个线程。
ExecutorService pool = Executors.newCachedThreadPool();
//固定大小的线程池,任务数 > 空闲线程数,得不到服务的任务置于队列
ExecutorService pool = Executors.newFixedThreadPool;
//退化的大小为1的线程池,由一个线程逐个执行提交的任务。
ExecutorService pool = Executors.newSingleThreadPool();
2. 把任务交给线程池:
//返回的对象可以调用isDone(),cancel(),isCancelled
Future<?> submit(Runnable task);
//get() 返回指定的result对象
Future<T> submit(Runnable task,T result);
//返回的对象将在计算结果准备好的时候得到它。
Future<T> submit(Callable<T> task);
3.用完一个线程池的时候,调用shutdown() 启动线程池的关闭序列。被关闭的执行器不再接受新的任务,当任务都结束后,线程池中的线程死亡。
4. 案例:给定一个目录,查找目录中文本文档内容包含指定关键字的文档的数量。
条件:目录、关键字
4.1 任务类(线程类)
/** 线程任务:计算目录中所有包含给定关键字的文件的数量。*/
class MatchCounter implements Callable<Integer>
{
private File directory;
private String keyword;
private ExecutorService pool;
private int count;
/**
* Constructs a MatchCounter.
* @param directory 给定的目录
* @param keyword 关键字
* @param pool 用来执行任务的线程池
*/
public MatchCounter(File directory, String keyword, ExecutorService pool)
{
this.directory = directory;
this.keyword = keyword;
this.pool = pool;
}
@Override
public Integer call()
{
count = 0;
try
{
File[] files = directory.listFiles();
//线程执行结果集合
List<Future<Integer>> results = new ArrayList<>();
for (File file : files)
//遍历给定目录中的所有文件
//如果是文件夹
if (file.isDirectory())
{
//递归
MatchCounter counter = new MatchCounter(file, keyword, pool);
Future<Integer> result = pool.submit(counter);
results.add(result);
}
//如果是文件,则调用search()方法 看是否包含关键字。
else
{
if (search(file)) count++;
}
for (Future<Integer> result : results)
try
{
int a = result.get();
count += result.get();
}
catch (ExecutionException e)
{
e.printStackTrace();
}
}
catch (InterruptedException e)
{
}
return count;
}
/**
* Searches a file for a given keyword.
* @param file the file to search
* @return true if the keyword is contained in the file
*/
public boolean search(File file)
{
try
{
try (Scanner in = new Scanner(file, "UTF-8"))
{
boolean found = false;
while (!found && in.hasNextLine())
{
String line = in.nextLine();
if (line.contains(keyword)) found = true;
}
return found;
}
}
catch (IOException e)
{
return false;
}
}
}
4.2 主程序
public class ThreadPoolTest
{
public static void main(String[] args) throws Exception
{
try (Scanner in = new Scanner(System.in))
{
System.out.print("请输入要查找的目录:");
String directory = in.nextLine();
System.out.print("请输入要查找的关键字:");
String keyword = in.nextLine();
ExecutorService pool = Executors.newCachedThreadPool();
MatchCounter counter = new MatchCounter(new File(directory), keyword, pool);
Future<Integer> result = pool.submit(counter);
try
{
System.out.println(result.get() + " 匹配的文件");
}
catch (ExecutionException e)
{
e.printStackTrace();
}
catch (InterruptedException e)
{
}
pool.shutdown();
int largestPoolSize = ((ThreadPoolExecutor) pool).getLargestPoolSize();
System.out.println("线程池最大数量 =" + largestPoolSize);
}
}
}
4.3 运行结果: