package gaoxin; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /* * * 第五期 *通过查询JDK自带的线程池,学习线程池的使用方法。 *并做以下练习:通过从线程池中获取的线程执行一个多线程任务(任务自定义)。 *想得满分,至少得写出两种线程池的用法,并附带详细的注释。 **/ //自定义一个线程类,继承了Thread class MyThread extends Thread { int i = 0; // 定义其中的run方法,方法是打印某线程在执行 public void run() { while (i++ < 3) System.out.println(this.getName() + "正在被执行。。。。。"); } } // 定义一个类,主要是为了让线程池执行里面的executeMethod方法。 class ThreadPool { //定义一个执行方法,形参接受一个线程池 public static void executeMethod(ExecutorService es) { //让该线程池添加10个MyThread线程并执行。 for (int x : new int[5]) { es.execute(new MyThread()); } } } //我分别用三个类来测试三个线程池,是因为线程池之间会相互影响。似乎同一个类中只能同时运行一个线程池? //单线程的线程池SingleThreadExecutor //这种线程池里只能同时运行一个线程,如果该线程在运行中因为异常结束了,线程池会重新创建一个线程继续执行。 class SingleThread { public static void main(String[] args) { //定义一个单线程的线程池 ExecutorService singleThread = Executors.newSingleThreadExecutor(); //提示这是执行哪个线程池 System.out.println("这是执行singleThreadPool的结果:"); //让它执行ThreadPool类中定义的执行方法。 ThreadPool.executeMethod(singleThread); //执行完就关闭该线程池 singleThread.shutdown(); //在打印的结果中我们可以看到,它是按顺序执行的,意味着它每次都只能同时运行一个任务。 } } //可重用固定数量的线程池FixedThreadPool //这种线程池里可同时运行指定数量的线程,每完成了一个任务时就再创建一个线程去执行任务,直到线程数量达到线程池可同 //时运行的最大值。 class FixedThread { public static void main(String[] args) { //同上 ExecutorService fixedThread = Executors.newFixedThreadPool(3); System.out.println("这是执行FixedThreadPool的结果:"); ThreadPool.executeMethod(fixedThread); fixedThread.shutdown(); //在打印的结果中,我们可以看到, //它在执行第一个任务后不断地创建新线程去执行余下的任务,直到线程数量达到了可允许的最大值。 //观察结果可发现,它同时执行的线程不超过3个。 } } //可缓存的线程池CachedThreadPool //它也是在完成一个线程任务后再创建一个线程,但不同于fixedThreadPool的是它没有限制数量, //它里面所能容纳的最大线程数量理论上是依据计算机内存的大小而定的。 //另外,当线程池大小超过需要运行的线程时,线程池就会回收空闲的线程。而任务增加时又将添加新线程来执行任务。 class CachedThread { public static void main(String[] args) { //同上 ExecutorService cachedThread = Executors.newCachedThreadPool(); System.out.println("这是执行CachedThreadPool的结果:"); ThreadPool.executeMethod(cachedThread); cachedThread.shutdown(); //在打印 的结果中,我们可以发现可缓存的线程池几乎可以同时运行所有线程。 } }