Java并发(2)

阻塞队列

阻塞线程可以协调多个线程之间的合作。

对于许多线程问题,可以通过使用一个或多个队列将其形式化, 生产者线程向队列插入元素,消费者线程则取出元素。

当试图向队列添加元素而队列已满,或者想从队列移出元素而队列为空时,阻塞队列导致线程阻塞。

阻塞队列的方法可以分为以下三类,取决于当队列满或空时它们的响应方式:

  • put(),take(),当队列满或空时阻塞。
  • add(),element(),remove(),当队列满或空时抛出异常
  • offer(),peek(),poll(),返回boolean或null。可以加超时参数

java.util.concurrent包提供的阻塞队列:

  • LinkedBlockingQueue,
  • LinkedBlockingDeque,首尾双端版本
  • ArrayBlockingQueue,
  • PriorityBlockingQueue,
  • DelayedQueue

线程安全的集合

java.util.concurrent包提供了线程安全的映射、有序集、队列的高效实现。ConcurrentHashMap,ConcurrentSkipListMap,ConcurrentSkipListSet,ConcurrentLinkedQueue。这些集合使用复杂的算法,通过允许并发访问数据结构的不同部分来使竞争最小化

size()不必在常规时间内返回,确定这样集合的大小需要遍历。对于庞大的并发散列映射,mappingCount()可以把大小作为long型返回。

集合返回弱一致性的迭代器,迭代器不一定能反映出它们被构造之后的所有修改,会尽量返回所有修改,但是它们不会将一个值返回两次,不会抛出ConcurrentModificationException异常。

并发的散列集合,可高效的支持大量的读者和一定数量的写者。

原子更新

replace(K key, V oldValue, V newValue); 替换动作

compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction); 提供键和一个计算新值的函数

merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction); value表示键不存在时的初始值

批操作

Java SE 8为并发散列映射提供了批操作,即使有其他线程在处理映射,也能安全执行。

批操作会遍历映射,处理遍历过程中找到的元素。

共三种不同的操作:

search搜索,为每个键或值提供一个函数,知道函数返回一个非null的结果

reduce归约,组合所有的键或值

forEach

并发集视图

没有ConcurrentHashSet,用ConcurrentHashMap创建

//使用newKeySet()创建线程安全的集
Set<String> words = ConcurrentHashMap.newKeySet();
Set<String> words = map.keySet("5");
words.add("e")

//已存在的映射的生成线程安全的集
Set<String> words = map.keySet("5");
words.remove("d");
words.add("e");

写数组的拷贝

CopyAndWriteArrayList,CopyAndWriteArraySet

所有的修改线程对底层数组进行复制。

并行数组算法

Arrays提供了大量的并行化操作。

parallelSort(int[] a),对一个基本类型或对象的数组排序

parallelSort(int[] a, int fromIndex, int toIndex),指定排序的边界

parallelSetAll(T[] array, IntFunction<? extends T> generator),用函数计算的值填充数组

callable与future

Runnable封装一个异步运行的任务,没有参数和返回值

Callable,可以包含参数

Future保存异步计算的结果,

FutureTask同时实现了Callable,Runnable

线程池

Executors.newCachedThreadPool(),

Executors.newFixedThreadPool()

Executors.newSingleThreadPool()

Executors.newScheduledThreadPool(),提供方法可以预定执行任务,或重复执行任务

Executors.newSingleThreadScheduledThreadPool()

使用完线程池后需要执行shutdown()关闭线程池

原文地址:https://www.cnblogs.com/minguo/p/11026412.html