这是我参与8月更文挑战的第27天,活动详情查看:8月更文挑战
1. Java的Thread类
- Thread.yield() 放弃本次被调度的机会,同时 随机 唤醒 一个 正在等待被调度的线程。
- Thread.sleep(long) 进入睡眠状态一段时间,同时不放弃监控器的拥有权。
- Thread.currentThread() 获取当前线程对象。
- Thread.interrupted() 判断线程当前是否中断,同时清除线程中断状态。
- 等待子线程结束后再继续运行:
t.join()。 - 判断线程当前状态:
t.isAlive()、t.isDaemon()、t.isInterrupted() - 获取线程执行优先级:
t.getPriority()。
2. Java多线程常用类
- Semaphore 信号量
- Exchanger 线程间通信
- CountDownLatch 一次同步
- CyclicBarrier 多次同步
- Phaser 动态调整的同步器
- Future/Callable 异步返回(是否有返回值或抛出异常)
- CompletionSerivce 异步边生产边处理
- ScheduledExecutorService 计划任务
- Fork-Join 分治并行编程
3. Java多线程集合类
- ConcurrentHashMap 哈希Map,读写操作时对链表头或红黑树根节点加锁。
- ConcurrentSkipListMap 跳表Map(对比上一个,数据天然有序,但查询效率略低)
- ConcurrentSkipListSet 跳表集合
- ConcurrentLinkedQueue 链式队列
- ConcurrentLinkedDeque 链式双端队列
- CopyOnWriteArrayList 基于数组的列表(写时复制)
- CopyOnWriteArraySet 基于数组的集合(写时复制)
顺手对比一下 Java 跟 Golang 的并发集合类
| Java | Golang |
|---|---|
| make(chan int, 0) | SynchronousQueue/ |
| make(chan int, INT_MAX) | new LinkedBlockingQueue/() |
| make(chan int, 10) | new ArrayBlockingQueue<Integer>(10) |
4. 线程池
由方法 new ThreadPoolExecutor(最多7个参数) 定义线程池。参数包含:
- 核心线程数目。
- 最大线程数目:核心用完的时候,可以继续创建线程直到达到 最大线程数目。
- 线程存活时间值:结合下一个参数,当线程无任务执行时,超过 核心线程数目 的多余线程等待多长时间就会主动销毁。
- 线程存储时间单位。
- 阻塞队列对象:没有足够的线程可以执行任务时,会把任务临时存到此队列中。
- 创建线程的工厂对象:实际运行时会调用此工厂的 newThread 来创建新的线程,通常用来自定义线程的名称/分组。
- 拒绝策略:当 阻塞队列 满了之后,使用的拒绝方式。
| 类 | 说明 | |
|---|---|
| Executors.newSingleThreadExecutor() | 最大1个线程可用的线程池 |
| Executors.newCachedThreadPool() | 无限个线程可用(按需创建)的线程池 |
| Executors.newFixedThreadPool(10) | 一定数量个线程可用的线程池 |
| Executors.newScheduledThreadPool(10) | 一定数量个支持按时间调度的线程可用的线程池 |
| Executors.newWorkStealingPool(10) | 一定数量个支持抢占式调度的线程可用的线程池,10表示并发度,如果不填,则默认为当前机器的CPU核心数 |