Java线程池和反射

  • 昨天学习了Java类库提供的容器类别,容器常用接口和多线程编程的相关知识。
  • 今天趁热打铁,学习使用Java内置线程池、线程安全的容器、lambda表达式和Java泛型编程。Java提供的这些封装好的常用工具,无疑给开发人员提供了极大的便利。
  • 回想起之前用C++实现web服务器,里面处理并发请求时,用到的线程池和阻塞队列,都是自己实现的。不过处于学习阶段,自行造轮子有利于理解底层的原理,也不算做无用功吧。
  • lambda表达式和泛型编程也同样在C++中学习并使用过,这里主要学习在Java中的使用语法。
  • 另外还了解了Java的反射机制,C++中没有这种机制,而这是框架设计的灵魂(所以Java的框架那么牛x?)

Java线程池

  • Java线程池顶级接口是java.util.concurrent.Executor,但是严格意义上Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是java.util.concurrent.ExecutorService

  • java.util.concurrent.Executor线程工厂类提供了一些静态工厂方法,用于生成一些常用的线程池,这些工厂方法主要有

    • static ThreadFactory defaultThreadFactory() :返回用于创建新线程的默认线程工厂。
    • static ExecutorService newCachedThreadPool():创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程。
    • static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) :创建一个根据需要创建新线程的线程池,但在可用时将重新使用以前构造的线程,并在需要时使用提供的ThreadFactory创建新线程。
    • static ExecutorService newFixedThreadPool(int nThreads):创建一个线程池,该线程池重用固定数量的从共享无界队列中运行的线程。
    • static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) :创建一个线程池,重用固定数量的线程,从共享无界队列中运行,使用提供的ThreadFactory在需要时创建新线程。
    • static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) :创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
    • static ScheduledExecutorService newScheduledThreadPool(int corePoolSize, ThreadFactory threadFactory) :创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
    • static ExecutorService newSingleThreadExecutor() :创建一个使用从无界队列运行的单个工作线程的执行程序。
    • static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory):创建一个使用单个工作线程运行无界队列的执行程序,并在需要时使用提供的ThreadFactory创建一个新线程。
    • static ScheduledExecutorService newSingleThreadScheduledExecutor():创建一个单线程执行器,可以调度命令在给定的延迟之后运行,或定期执行。
    • static ScheduledExecutorService newSingleThreadScheduledExecutor(ThreadFactory threadFactory) :创建一个单线程执行器,可以调度命令在给定的延迟之后运行,或定期执行。
    • static ExecutorService newWorkStealingPool():创建使用所有 available processors作为其目标并行级别的工作窃取线程池。
    • static ExecutorService newWorkStealingPool(int parallelism):创建一个维护足够的线程以支持给定的并行级别的线程池,并且可以使用多个队列来减少争用。
  • Callable和Future

    • Runnable封装一个异步运行的任务,可以把它想象成一个没有参数和返回值的异步方法。而Callable和Runnable类似,但是有返回值。Callable接口是一个参数化的模型,只有一个方法Call
      public interface Callable{
             
      	V call () throws Exception;
      }
      
      类型参数是返回值的类型。如,Callable<Integer>表示一个最终返回Integer对象的异步计算
    • Future保存异步计算的结果。可以启动一个计算,将Future对象交给某个线程,然后忘掉它。这个Future对象的所有者在计算号之后就可以获得结果。Future接口有以下方法
      • boolean cancel(boolean mayInterruptIfRunning) :取消执行此任务,若任务未开始则此任务不再执行。
      • V get():等待计算完成,然后获得其结果,方法会阻塞直到结果可用。
      • V get(long timeout, TimeUnit unit) :等待计算完成,然后获得其结果,方法会阻塞直到结果可用或者超时。
      • boolean isCancelled() :如果此任务在正常完成之前被取消,则返回 true 。
      • boolean isDone() :如果任务已完成返回 true。
    • 执行Callable的一种方法是使用FutureTask,它实现了Future和Runnable接口,所以可以构造一个线程来运行这个任务:
      Callable<Integer> task = ...;
      var ft = new FutureTask<Integer>(task);
      new Thread(ft).start();
      Integer result = ft.get();	// 结果可能在未来,阻塞等待
      
  • 通过调用上述线程池构造方法可以创建一个ExecutorService线程池对象,该对象主要方法如下

    • 提交指定的Runnable或Callable对象到ExecutorService对象来执行
      • Future<T> submit(Callable<T> task)
      • Future<?> submit(Runnable task)
      • Future<T> submit(Runnable task, T result)
    • 关闭服务,完成已经提交的任务但不再接受新的任务
      • void shutdown()
  • 使用线程池的步骤

    • 调用Executor类的静态工厂方法newCacheThreadPoolnewFixedThreadPool创建线程池ExecutorService对象
    • 新建一个对象,实现Runnable或者Callable接口,重写run方法,设置线程任务
    • 调用ExecutorService对象的submit提交Runnable或者Callable对象
    • 保存好返回的Future对象,以便得到结果或者取消任务
    • 当不需要再提交任何任务时,调用shutdown

Java线程安全集合

  • Java类库提供了一些线程安全的集合,以供多线程环境下,并发修改一个数据结构的需要。而在C++中,STL容器库都不是线程安全的,需要自行加锁实现对容器操作的同步
  • Java类库提供的线程安全集合主要有阻塞队列接口,高效的映射、集和队列接口(无锁实现)
  • 实现阻塞队列接口(Interface BlockingQueue<E>)的子类主要有
    • ArrayBlockingQueue<E>:实现一个有指定容量和公平性设置的阻塞队列,队列底层实现为一个循环数组
    • LinkedBlockingDeque<E>:实现一个阻塞双向队列,可以构造为指定容量或容量无上限的阻塞双向队列,底层实现为双向链表
    • LinkedBlockingQueue<E>:实现一个阻塞队列,可以构造为指定容量或容量无上限的阻塞队列,底层实现为双向链表
    • PriorityBlockingQueue<E>:实现一个容量无上限的阻塞有限队列,底层实现为一个堆,可以通过指定比较器构造堆
  • 线程安全的高效映射集合
    • ConcurrentHashMap<k, v>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值