1.Jdk的多任务执行框架缓存
JDK提供了一套线程框架Executor来帮助开发者有效的进行线程控制,Executors扮演线程工厂的角色,其建立线程的方法以下框架
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(10); //command 就是一个Thread ScheduledFuture<?> scheduledTask = scheduler.scheduleWithFixedDelay(command,5,1, TimeUnit.SECONDS);
若Executors工厂类没法知足咱们的需求,能够本身去建立自定义的线程池。自定义线程池的构造方法以下ide
public ThreadPoolExecutor(int corePoolSize,//核心线程数 int maximumPoolSize,//最大线程数 long keepAliveTime,//线程的空闲时间 TimeUnit unit,//给定单元粒度的时间段 BlockingQueue<Runnable> workQueue,//有界、无界队列 RejectedExecutoionHandler handler//任务拒绝策略 ){.....}
使用什么队列对该构造方法来讲比较关键函数
若是实际线程数>corePoolSize,则将任务添加到缓存队列 若是缓存队列已满 ,总线程<maximumPoolSize, 则建立线程 总线程>maximumPoolSize, 则执行拒绝策略
若有任务须要执行 若是实际线程数<corePoolSize,则建立线程 若是实际线程数>corePoolSize,则将任务添加到缓存队列, 直到资源耗尽
BlockingQueue<Runnable> queue = //new LinkedBlockingQueue<Runnable>();//无界队列 new ArrayBlockingQueue<Runnable>(10);//有界队列 ExecutorService executor = new ThreadPoolExecutor( 5, //core 10, //max 120L, //120s TimeUnit.SECONDS, queue);
JDK的拒绝策略工具
JDK提供的拒绝策略不友好,能够自定义拒绝策略,实现RejectedExecutionHandler接口(添加日志等等)性能
public class MyRejected implements RejectedExecutionHandler { public MyRejected(){} @Override public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) { System.out.println("自定义处理"); System.out.println("当前被拒绝的任务为"+r.toString()); } }
2.Concurrent.util工具类详解优化
CyclicBarrier
假设每个线程表明一个运动员,当运动员都准备好了,才能一块儿出发。ui
CyclicBarrier barrier = new CyclicBarrier(3);
CountDownLatch
常常用于监听某些初始化操做,当初始化执行完毕之后,通知主线程继续工做this
final CountDownLatch countDownLatch = new CountDownLatch(2);
Callable 和Future使用
Futrue模式费用适合在处理耗时很长的业务逻辑进行使用,能够有效的减少系统的影响,
提升系统的吞吐量线程
public class UseFuture implements Callable<String>{ private String para; public UseFuture(String para){ this.para = para; } /** * 这里是真实的业务逻辑,其执行可能很慢 */ @Override public String call() throws Exception { //模拟执行耗时 Thread.sleep(5000); String result = this.para + "处理完成"; return result; } //主控制函数 public static void main(String[] args) throws Exception { String queryStr = "query"; //构造FutureTask,而且传入须要真正进行业务逻辑处理的类, //该类必定是实现了Callable接口的类 FutureTask<String> future = new FutureTask<String>(new UseFuture(queryStr)); FutureTask<String> future2 = new FutureTask<String>(new UseFuture(queryStr)); //建立一个固定线程的线程池且线程数为1, ExecutorService executor = Executors.newFixedThreadPool(2); //这里提交任务future,则开启线程执行RealData的call()方法执行 //submit和execute的区别: //第一点是submit能够传入实现Callable接口的实例对象, // 第二点是submit方法有返回值 Future f1 = executor.submit(future); //单独启动一个线程去执行的 Future f2 = executor.submit(future2); System.out.println("请求完毕"); try { //这里能够作额外的数据操做,也就是主程序执行其余业务逻辑 System.out.println("处理实际的业务逻辑..."); Thread.sleep(1000); } catch (Exception e) { e.printStackTrace(); } //调用获取数据方法,若是call()方法没有执行完成,则依然会进行等待 System.out.println("数据:" + future.get()); System.out.println("数据:" + future2.get()); executor.shutdown(); } }
Semaphore信号量
能够控制系统的流量,拿到线程的信号量则访问不然等待
经过acquire和release来获取和释放线程
final Semaphore semp = new Semaphore(5);
3.锁的高级深化
Lock and Condition
使用synchronized关键字能够实现线程间的同步互斥工做
使用Lock对象也能够实现同步互斥
若是多个线程之间须要实现协做 使用Object的wait和nofity,notifyAll
在使用Lock的时候可使用一个新的等待/通知的类Condition 只针对一个具体的锁
public class UseCondition { private Lock lock = new ReentrantLock(); private Condition condition = lock.newCondition(); public void method1(){ try { lock.lock(); System.out.println("当前线程:" + Thread.currentThread().getName() + "进入等待状态.."); Thread.sleep(3000); System.out.println("当前线程:" + Thread.currentThread().getName() + "释放锁.."); condition.await(); // Object wait System.out.println("当前线程:" + Thread.currentThread().getName() +"继续执行..."); condition.signal(); //Object notify } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }
ReentrantLock重入锁
private Lock lock = new ReentrantLock(boolean isFair);//是否为公平锁
ReentrantReadWriteLock读写锁
核心是实现读写分离 在都多写少的状况下 性能高于重入锁
public class UseReentrantReadWriteLock { private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock(); private ReadLock readLock = rwLock.readLock(); private WriteLock writeLock = rwLock.writeLock(); public void read(){ try { readLock.lock(); System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..."); Thread.sleep(3000); System.out.println("当前线程:" + Thread.currentThread().getName() + "退出..."); } catch (Exception e) { e.printStackTrace(); } finally { readLock.unlock(); } } public void write(){ try { writeLock.lock(); System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..."); Thread.sleep(3000); System.out.println("当前线程:" + Thread.currentThread().getName() + "退出..."); } catch (Exception e) { e.printStackTrace(); } finally { writeLock.unlock(); } } }
锁的优化