并发程序—线程池
来源:互联网 发布:中建西南院待遇知乎 编辑:程序博客网 时间:2024/05/02 00:26
一.JDK线程池
1.jdk的线程池由ThreadPoolExecutor()演化而来
new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
ExecutorService es = Executors.newCachedThreadPool();
new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
es = Executors.newFixedThreadPool(10);
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())
es = Executors.newSingleThreadExecutor();
2.workQueue的分类
1)直接提交队列:SynchronizedQueue
当线程数到了corePoolSize,在后来的任务就会提交到workqueue,而该实现的队列只要有插入操作,就会立即执行提交操作,让线程池新建线程执行任务
若此时线程个数超过maximumPoolSize,就会执行决绝策略,所以通常用该任务队列的线程池,要设置很大的maxPoolSize
2)有界任务队列:ArrayBlockingQueue
public ArrayBlockingQueue(int capacityu)
该队列的创建有容量上线,当线程数到达coolPoolSize,任务会加到该队列中,队列满时,新增线程到maxPoolSize,若大于maxPoolSize,执行决绝策略
3)无界队列:LinkedBlockingQueue
无界队列的线程池当线程数大于corePoolSize后,任务一脸表的形式加入到队列中,知道内存耗尽
4)优先任务队列:priorityBlockingQueue
该队列中的任务会根据任务的优先级选择执行,他是无界队列
[注]:newFixedThreadPool()的线程数固定,所以corePoolSize和maxPoolSize相等,采用无界队列,让其在系统频繁增加爱任务的时候,会导致内存泄漏
newCachedThreadPool()也采用无界队列实现,他的corePoolSize为0,说明初始时没有线程,空闲的线程会在60s后回收
3.RefusedExecutionHandler的分类
1)AbortPolicy:直接抛出异常
2)CallerRunsPolicy:在调用这的线程中执行多出的任务
3)DiscardOldestPolicy:丢弃最老的任务请求,(即将处理的任务),尝试提交当前任务
4)DiscardPolicy:丢弃外发处理的任务
[注]:线程池大小:CPU数量×预期的CPU使用率×(1+等待时间与计算时间的比)
1.jdk的线程池由ThreadPoolExecutor()演化而来
public ThreadPoolExecutor(int corePoolSize, //线程池的线程数量 int maximumPoolSize, //线程池的最大线程数量 long keepAliveTime, //超过corePoolSize的空闲线程,回在多长时间后销毁 TimeUnit unit, //keepAliveTime的时间单位 BlockingQueue<Runnable> workQueue) //已提交单尚未执行的任务 ThreadFactory threadFactory, //创建线程的工厂,默认即可 RejectedExecutionHandler handler) //拒绝策略
new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
ExecutorService es = Executors.newCachedThreadPool();
new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
es = Executors.newFixedThreadPool(10);
new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>())
es = Executors.newSingleThreadExecutor();
2.workQueue的分类
1)直接提交队列:SynchronizedQueue
当线程数到了corePoolSize,在后来的任务就会提交到workqueue,而该实现的队列只要有插入操作,就会立即执行提交操作,让线程池新建线程执行任务
若此时线程个数超过maximumPoolSize,就会执行决绝策略,所以通常用该任务队列的线程池,要设置很大的maxPoolSize
2)有界任务队列:ArrayBlockingQueue
public ArrayBlockingQueue(int capacityu)
该队列的创建有容量上线,当线程数到达coolPoolSize,任务会加到该队列中,队列满时,新增线程到maxPoolSize,若大于maxPoolSize,执行决绝策略
3)无界队列:LinkedBlockingQueue
无界队列的线程池当线程数大于corePoolSize后,任务一脸表的形式加入到队列中,知道内存耗尽
4)优先任务队列:priorityBlockingQueue
该队列中的任务会根据任务的优先级选择执行,他是无界队列
[注]:newFixedThreadPool()的线程数固定,所以corePoolSize和maxPoolSize相等,采用无界队列,让其在系统频繁增加爱任务的时候,会导致内存泄漏
newCachedThreadPool()也采用无界队列实现,他的corePoolSize为0,说明初始时没有线程,空闲的线程会在60s后回收
3.RefusedExecutionHandler的分类
1)AbortPolicy:直接抛出异常
2)CallerRunsPolicy:在调用这的线程中执行多出的任务
3)DiscardOldestPolicy:丢弃最老的任务请求,(即将处理的任务),尝试提交当前任务
4)DiscardPolicy:丢弃外发处理的任务
[注]:拒绝策略实现的接口:
interface RejectExecutionHandler{ void rejectExecution(Runnable r,Thread t)}
自定义线程池可以实现任务执行谦和执行后的操作:
//自定义线程池class MyThreadPoolExecutor extends ThreadPoolExecutor{ public MyThreadPoolExecutor() { super(100, 200, 0, TimeUnit.SECONDS, new PriorityBlockingQueue<Runnable>()); } @Override protected void afterExecute(Runnable r, Throwable t) { System.out.println("end tId:"+Thread.currentThread().getName()); System.out.println("end tName:"+Thread.currentThread().getName()); System.out.println("end poolSize:"+this.getPoolSize()); // 当前线程池中线程的数量 } @Override protected void beforeExecute(Thread t, Runnable r) { System.out.println("start tId:"+t.getId()+" tName:"+t.getName()); } }
/*Runnable*/class MyRunnable implements Runnable,Comparable<MyRunnable>{ protected int level; public MyRunnable(int level) { super(); this.level = level; } @Override public void run() { try { Thread.sleep(1010); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.level+"等级"); } @Override public int compareTo(MyRunnable o) { return this.level>o.level ? 0:-1; } }
/*调用*/public static void main(String[] args) throws InterruptedException { ExecutorService es = new MyThreadPoolExecutor(); for(int i=0;i<1000;i++){ es.execute(new MyRunnable(i)); } /* 95等级 94等级 99等级 100等级 //初始的100个空闲线程一次执行,超过后加入优先队列,执行等级高的线程 999等级 998等级 997等级 */ }
二.简易的线程池
public class MyThreadPool { private static MyThreadPool instance = null; //线程池的单例模式 private List<MyThread> threadList; //线程队列,存放的都是挂起的线程 private int count; //加入线程数 private boolean shutDown = false; private MyThreadPool(){ this.threadList = new Vector(5); this.count = 0; } public int getSize(){ return this.threadList.size(); } public static synchronized MyThreadPool getInstance(){ if(instance == null) instance = new MyThreadPool(); return instance; } public int getCount() { return count; } public synchronized void add(MyThread myThread){ if(!shutDown){ threadList.add(myThread); //MyThread是一个用不停止的线程,等待接受真实线程 }else{ myThread.stop(); } } /* 1.使用空闲的线程接受runnable<span style="white-space:pre"></span>--所谓空闲,就是把线程的处理逻辑写在一个while(true)里,在这个无限循环中,逻辑处理完,就wait(),使之挂起 * 2.若没有空闲线程则创建线程,并开启线程 */ public synchronized void start(Runnable target){ MyThread myThread = null; if(threadList.size()>0){ int lastIndex = threadList.size()-1; myThread = threadList.get(lastIndex); threadList.remove(lastIndex);//runnable的run()执行后会停止对象运行,相应的也要从list中删除MyThread myThread.setTarget(target); // 在永不停止的线程中运行目标线程 }else{ count++; myThread = new MyThread(this, "myThread #"+count, target); myThread.start(); this.threadList.add(myThread); } } public synchronized void shutDown(){ this.shutDown = true; for(Thread t:threadList){ t.stop(); } }}
//用一个永不停止的线程接收目标targetclass MyThread extends Thread{ private MyThreadPool myThreadPool = null; private Runnable target = null; private boolean shutDown = false; private boolean idle = false; // 线程是否空闲 public MyThread(MyThreadPool myThreadPool,String name,Runnable target) { super(name); // 给产生线程加上名字 this.myThreadPool = myThreadPool; this.target = target; } /* 1.永不结束 * 2.执行加入的runnable * 3.执行完加入线程池队列,挂起继续等待下一个runnable */ @Override public void run() { while(!shutDown){ idle = false; //线程在运行中 if(target!=null) this.target.run(); ////Runnable执行结束后,线程空闲,不释放,加入线程池 idle = true; try { synchronized (this) { myThreadPool.add(this); wait(); //线程挂起,等待其他线程加入 } } catch (InterruptedException e) { e.printStackTrace(); } idle = false; //runnable加入后,线程换醒后,不在空闲 } } public synchronized void setTarget(Runnable target) { this.target = target; notifyAll(); //当notify()后,线程被唤醒,且回到wait()的地方, 继续执行下面的代码 } }/**调用国策后嗯与下方一样*/
[注]:线程池大小:CPU数量×预期的CPU使用率×(1+等待时间与计算时间的比)
0 0
- 并发程序—线程池
- 【Java】线程并发拷贝程序
- 【Linux】线程并发拷贝程序
- java并发——多线程、线程池、并发集合
- Java并发——线程池原理
- Java并发之——线程池
- java并发——线程池
- 并发编程 — 详解线程池
- 并发编程 — 初解线程池
- 并发编程 — 详解线程池
- 一个并发程序开多少线程合适?
- 【Linux】管道模拟,线程并发拷贝程序
- 1、java 线程与并发程序编写--线程本质
- 利用ACL库开发高并发半驻留式线程池程序
- [置顶] 利用ACL库开发高并发半驻留式线程池程序
- Java线程并发库之线程池
- 线程并发库<二>_线程池
- 线程、线程池、并发、同步、异步、锁
- 12.27(2)
- 阻止GDB依附
- GIT大话流程介绍
- linux-共享内存
- soj 4392 double类型的使用和二分查找
- 并发程序—线程池
- [Elasticsearch] 控制相关度 (五) - function_score查询及field_value_factor,boost_mode,max_mode参数
- Java的IO流之文件随机读写
- Firemonkey for IOS OSX 10.9 XCode6.1
- poj解题报告——3267
- Android初识JNI-搭建NDK开发环境
- Java EE 开源项目
- [Elasticsearch] 控制相关度 (六) - function_score查询中的filter,functions及random_score参数
- JDBC 直连TPYE 4 +绑定变量范例