顾名思义,线程池就是存放线程的池子。直接用线程不就好了吗,为什么还需要线程池呢?
相比进程,线程已经轻量很多了,创建和销毁线程消耗的资源会少很多,但终究还是有消耗的。为了进一步降低消耗,我们需要用到线程池。需要用到线程时不用申请,直接从线程池中取,用完之后也不用销毁,再放进线程池。
标准库中的线程池(简化版本):
1 2 3 4 5 6 7 8 9
| public static void main(String[] args) { ExecutorService pool = Executors.newFixedThreadPool(10); pool.submit(new Runnable() { @Override public void run() { System.out.println("hello"); } }); }
|
模拟实现一个简化版本的线程池:
- 描述任务:直接用Runnable接口即可
- 组织任务:用到阻塞队列
- 描述工作线程:创建Worker类继承Thread,重写run方法,从阻塞队列中取任务,然后执行任务
- 组织工作线程:实例化工作线程,加入到线程池,启动线程
- 提交任务:往线程池中添加任务(具体是将任务添加到阻塞队列)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| public class ThreatPool { BlockingDeque<Runnable> queue = new LinkedBlockingDeque<>(); static class Worker extends Thread{ private BlockingDeque<Runnable> queue = null; public Worker(BlockingDeque<Runnable> queue) { this.queue = queue; }
@Override public void run() { while(true){ try { Runnable runnable = queue.take(); runnable.run(); } catch (InterruptedException e) { e.printStackTrace(); } } } } List<Worker> workers = new LinkedList<>(); public ThreatPool(int n) { for (int i = 0; i < n; i++) { Worker worker = new Worker(queue); workers.add(worker); worker.start(); } } public void sumbit(Runnable runnable) throws InterruptedException { queue.put(runnable); }
public static void main(String[] args) throws InterruptedException { ThreatPool pool = new ThreatPool(10); for (int i = 0; i < 1000; i++) { int workId = i; pool.sumbit(new Runnable() { @Override public void run() { System.out.println("任务:"+workId+Thread.currentThread().getName()); } }); } } }
|