java8多线程、队列集合和线程池

1. 线程的取消和中断

  • interrupt() 中断线程,本质是将线程的中断标志位设为true,其他线程向需要中断的线程打个招呼。是否真正进行中断由线程自己决定
  • isInterrupted() 线程检查自己的中断标志位
  • 静态方法Thread.interrupted() 将中断标志位复位为false

2. volatile

  多个线程同时访问一个共享的变量的时候,每个线程的工作内存有这个变量的一个拷贝,变量本身还是保存在共享内存中。
  Violate修饰字段,对这个变量的访问必须要从共享内存刷新一次。最新的修改写回共享内存。可以保证字段的可见性。绝对不是线程安全的,没有操作的原子性。
3. join
  线程A,执行了thread.join(),线程A等待thread线程终止了以后,A在join后面的语句才会继续执行
4. map
  • putIfAbsent(key,value)方法原子性

如果key对应的value不存在,则put进去,返回null。否则不put,返回已存在的value。

  • boolean remove(Object key, Object value)

如果key对应的值是value,则移除K-V,返回true。否则不移除,返回false。

  • boolean replace(K key, V oldValue, V newValue)

如果key对应的当前值是oldValue,则替换为newValue,返回true。否则不替换,返回false。

5. ConcurrentSkipListMap  TreeMap的并发实现 跳跃表其实也是一种通过“空间来换取时间”的一个算法,通过在每个节点中增加了向前的指针,从而提升查找的效率。

    ConcurrentSkipListSet    TreeSet的并发实现

 CopyOnWriteArrayList  写操作的时候复制,当有新元素添加到CopyOnWriteArrayList的时候,先从原有数组里面拷贝一份出来,然后在新的数组做写操作,最后将原有的数组指向新的数组,是线程安全的,整个add操作都是在锁的机制下操作的。缺点一是由于写操作需要拷贝数组,消耗内存,缺点二,不适合实时读的场景。CopyOnWriteArrayList适合读多写少的场景。CopyOnWriteArrayList特点是读写分离、最终一致性、使用时另外开辟空间,解决并发冲突。CopyOnWriteArrayList的读操作都是在原数组读取的,不需要加锁的,写操作是需要加锁的。

6.阻塞队列  队列满额,线程数据无法插入,就会被阻塞等待数据插入,直到队列可以插入为止,当队列为空时,会被阻塞,直到数据插入后才可以唤醒线程移除。阻塞队列使用 Condititon、Lock,在元素进入使用等待wait(),出队使用唤醒。
 
方法抛出异常返回值一直阻塞超时退出
插入 Add offer put offer
移除 remove poll take poll
检查 element peek 没有 没有

ArrayBlockingQueue  数组结构组成有界阻塞队列,先进先出原则,初始化必须传大小,take和put时候用的同一把锁。

LinkedBlockingQueue  链表结构组成的有界双向阻塞队列,先进先出原则,可以在队列的两端插入和移除,xxxFirst头部操作,xxxLast尾部操作。初始化可以不传大小,put,take锁分离。

PriorityBlockingQueue  支持优先级排序的无界阻塞队列,自然顺序升序排列,更改顺序:类自己实现compareTo()方法,初始化PriorityBlockingQueue指定一个比较器Comparator

DelayQueue  使用了优先级队列的无界阻塞队列,支持延时获取,队列里的元素要实现Delay接口。DelayQueue非常有用,可以将DelayQueue运用在以下应用场景:

缓存系统的设计:可以用DelayQueue保存缓存元素的有效期,使用一个线程循环查询DelayQueue,一旦能从DelayQueue中获取元素时,表示缓存有效期到了。还有订单到期,限时支付等.

1.客户端长时间占用连接的问题,超过这个空闲时间了,可以移除的

2.处理长时间不用的缓存:如果队列里面的对象长时间不用,超过空闲时间,就移除

3.任务超时处理

SynchronousQueue  不存储元素的阻塞队列,每个put操作必须要等take操作

LinkedTransferQueue  链表结构组成的无界阻塞队列,Transfer,tryTransfer,生产者put时,当前有消费者take,生产者直接把元素传给消费者

7. CyclicBarrier和CountDownLatch的区别

CountDownLatch的计数器只能使用一次,而CyclicBarrier的计数器可以使用reset()方法重
置,CountDownLatch.await一般阻塞主线程,所有的工作线程执行countDown,而CyclicBarrierton通过工作线程调用await从而阻塞工作线程,直到所有工作线程达到屏障。

CyclicBarrier可以用于多线程计算数据,最后合并计算结果的场景。

 

posted @ 2021-01-29 18:05  agasha  阅读(473)  评论(0编辑  收藏  举报