方法1:Java自带的线程池
采用Executors的factory method创建了固定大小的线程池,采用execute()方法添加Runnable Task。
1 ExecutorService threadPool = Executors.newFixedThreadPool(2); 2 for (int i = 0; i < 4; i++) 3 threadPool.execute(new InnerWork(i + "")); 4 threadPool.shutdown();
内部实现是采用LinkedBlockingQueue。
/** * Creates a thread pool that reuses a fixed number of threads * operating off a shared unbounded queue. At any point, at most * <tt>nThreads</tt> threads will be active processing tasks. * If additional tasks are submitted when all threads are active, * they will wait in the queue until a thread is available. * If any thread terminates due to a failure during execution * prior to shutdown, a new one will take its place if needed to * execute subsequent tasks. The threads in the pool will exist * until it is explicitly {@link ExecutorService#shutdown shutdown}. * * @param nThreads the number of threads in the pool * @return the newly created thread pool * @throws IllegalArgumentException if <tt>nThreads <= 0</tt> */ public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); }
方法2:采用BlockingQueue编程实现一个大小可变的线程池。
思路:
1.线程池的功能有①执行线程任务execute();②停止线程任务shutdown()。
2.用BlockingQueue<Runnable> 存放Runnable Task,add(Runnable task)添加Task,take()取出Task执行。List<Thread> 保存线程,为了实现shutdown().
3.内部类的实现控制线程池。内部类采用while死循环来保证运行“实际运行的Task”运行,死循环可以保持线程不消亡。
实现的线程池:MyThreadPool.java
1 import java.util.ArrayList; 2 import java.util.List; 3 import java.util.concurrent.BlockingQueue; 4 import java.util.concurrent.LinkedBlockingQueue; 5 6 public class MyThreadPool { 7 static BlockingQueue<Runnable> queue; 8 List<Thread> threads; 9 10 MyThreadPool(int threadNum) { 11 MyThreadPool.queue = new LinkedBlockingQueue<Runnable>(); 12 this.threads = new ArrayList<Thread>(threadNum); 13 for (int i = 0; i < threadNum; i++) { 14 Thread t = new InnerThread(); 15 t.start(); 16 threads.add(t); 17 } 18 } 19 20 //设计的思路:利用while死循环来控制线程的启动。注意:while(true)的位置在try里面,这样捕获到异常才可以跳出while循环。 21 static class InnerThread extends Thread { 22 public void run() { 23 try { 24 while (true) { 25 queue.take().run(); 26 } 27 } catch (InterruptedException e) { 28 System.out.println("One thread is dying!"); 29 } 30 } 31 } 32 33 void execute(Runnable task) { 34 queue.add(task); 35 } 36 37 void shutdown() { 38 for (Thread t : threads) { 39 t.interrupt(); 40 } 41 } 42 }
使用线程池:Main.java
1 //Main.java 2 import java.util.*; 3 import java.util.concurrent.ExecutorService; 4 import java.util.concurrent.Executors; 5 6 public class Main { 7 static List<Integer> block = new LinkedList<Integer>(); 8 static { 9 block = Collections.synchronizedList(block); 10 for (int i = 0; i < 1500; i++) { 11 block.add(i); 12 } 13 } 14 15 public static void main(String[] args) { 16 // 方法1:Java线程池的用法 17 // ExecutorService threadPool = Executors.newFixedThreadPool(2); 18 // 方法2:自己实现的线程池 19 MyThreadPool threadPool = new MyThreadPool(2); 20 for (int i = 0; i < 10; i++) 21 threadPool.execute(new InnerWork(i + "")); 22 threadPool.shutdown(); 23 } 24 25 static class InnerWork implements Runnable { 26 String name; 27 28 public InnerWork(String name) { 29 this.name = name; 30 } 31 32 @Override 33 public void run() { 34 for (int i = 0; i < 100; i++) 35 System.out.println(name + " : " + block.remove(0)); 36 } 37 38 } 39 }