JUC包工具类介绍一
Queue
BlockingQueue
BlockingQueue 多线程操作的队列抽象。线程对BlockingQueue的操作包括插入元素和获取元素。主要提供以下三组接口:
- 抛出异常型接口: add(o), remove(o), element(),当操作无法执行,抛出异常。
- 返回操作结果型接口: offer(o) , poll(), peek(),返回操作的结果值,如操作失败不抛出异常,而返回特定值。
- 阻塞型接口:put(o), take(), 当操作无法进行时,阻塞直到可行。
- 超时型接口:offer(o,timeout, timeunit), poll(timeout,timeunit),当操作不可行时阻塞指定时间,超时后返回特定值。
BlockingQueue的实现类有以下工具类:
-
-
- ArrayBlockingQueue
-
使用数组来实现一个有边界的BlockingQueue, 数组大小在初始时指定,后期无法改变。ArrayBlockingQueue 元素的插入和读取依照FIFO(先入先出)的模式。
BlockingQueue queue = new ArrayBlockingQueue(1024); queue.put("1"); Object object = queue.take(); |
-
-
- LinkedBlockingQueue
-
使用链表实现的BlockingQueue, LinkedBlockingQueue可以指定容量上限,当不指定时则容量无限制,元素的插入和读取依照FIFO(先入先出)的模式。
BlockingQueue<String> unbounded = new LinkedBlockingQueue<String>(); BlockingQueue<String> bounded = new LinkedBlockingQueue<String>(1024); bounded.put("Value"); String value = bounded.take(); |
-
-
- PriorityBlockingQueue
-
容量无限的队列, 插入PriorityBlockingQueue的元素必须实现java.lang.Comparable接口,队列元素插入时按照元素的排序进行插入。
BlockingQueue queue = new PriorityBlockingQueue(); //String implements java.lang.Comparable queue.put("Value"); String value = queue.take(); |
-
-
- SynchronousQueue
-
同步队列, 一个线程插入或读取元素操作将阻塞直到另一个线程读取或插入元素。实际中应用较少。
-
-
- DelayQueue
-
延迟队列, 插入Queue的元素实现Delayed接口,返回元素的延迟时间。对队列元素的获取将阻塞至延迟时间的达到。
public interface Delayed extends Comparable<Delayed< { public long getDelay(TimeUnit timeUnit); } //示例 public class DelayQueueExample { public static void main(String[] args) { DelayQueue queue = new DelayQueue(); Delayed element1 = new DelayedElement(); queue.put(element1); Delayed element2 = queue.take(); } } |
BlockingDequeue
BlockingDequeue 表示一个双向的BlockingQueue,线程可以再队列头或尾部进行元素的插入和读取。一个实现类为:LinkedBlockingDequeue。
BlockingDeque<String> deque = new LinkedBlockingDeque<String>(); deque.addFirst("1"); deque.addLast("2"); String two = deque.takeLast(); String one = deque.takeFirst(); |
ConcurrentMap
ConcurrentMap是Map接口的并发版本, JUC提供的实现类为:ConcurrentHashMap。ConcurrentHashMap和HashTable类似,区别在于HashTable通过锁定整个Table来提供线程安全,而ConcurrentHashMap只锁定Map的部分元素来提供更高的并发性。
ConcurrentMap concurrentMap = new ConcurrentHashMap(); concurrentMap.put("key", "value"); Object value = concurrentMap.get("key"); |
ConcurrentNavigableMap 扩展了concurrentMap和NavigableMap接口,提供了获取原Map的子Map视图的方法, 如headMap, tailMap。实现类为:ConcurrentSkipListMap。
ConcurrentNavigableMap map = new ConcurrentSkipListMap(); map.put("1", "one"); map.put("2", "two"); map.put("3", "three"); ConcurrentNavigableMap tailMap = map.tailMap("2"); |
线程池
ExecutorService
ExecutorService: 表示可以一步执行任务的执行器服务。Executors类提供了构建各种ExecutorService实现的静态方法。包括:
ThreadPoolExecutor
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } |
如果线程池中的现成数量少于corePoolSize参数, 当任务被提交到线程池时,将创建新的现成执行,即使此时线程池中还存在空闲线程。当线程队列已满,并且线程数已经达到或超过corePoolSize,但小于maximumPoolSize时,将创建线程执行任务。当线程空闲,并且线程数量大于corePoolSize,空闲线程将释放。
scheduledExecutorService 提供对任务进行有计划的执行,比如延后执行,按照特定频率执行等,如以下方法:
schedule (Runnable task, long delay, TimeUnit timeunit)
scheduleAtFixedRate (Runnable, long initialDelay, long period, TimeUnit timeunit)
scheduleWithFixedDelay (Runnable, long initialDelay, long period, TimeUnit timeunit)
Executors提供创建ScheduledExecutorService方法,如:
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
return new ScheduledThreadPoolExecutor(corePoolSize);
}
ThreadPoolExecutor
ThreadPoolExecutor 是JUC提供的ExecutorService实现, 通常不直接使用ThreadPoolExecutor的构造方法创建ThreadPoolExecutor对象, 而是使用java.util.concurrent.Executors提供的静态方法获取。如:
public static ExecutorService newFixedThreadPool(int nThreads) { return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); } |
线程协作
CountDownLatch
CountDownLatch用于一个或多个线程等待一个操作集合的完成。等待线程和执行线程使用同一个Latch对象, 执行线程通过latch.countDown();对latch执行进行登记,等待进程使用latch.wait()方法等待指定数量的latch.countDown()的执行完成。
CountDownLatch latch = new CountDownLatch(3); latch.countDown(); latch.wait(); |
CyclicBarrier
CyclicBarrier 用于设定多个线程等待协同,所有线程等待都到达CycliBarrier.wait()时,触发特定操作(BarrierAction),等待线程继续执行。
public class CyclicBarrierRunnable implements Runnable{ CyclicBarrier barrier1 = null; CyclicBarrier barrier2 = null; public CyclicBarrierRunnable( CyclicBarrier barrier1, CyclicBarrier barrier2) { this.barrier1 = barrier1; this.barrier2 = barrier2; } public void run() { try { Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " waiting at barrier 1"); this.barrier1.await(); Thread.sleep(1000); System.out.println(Thread.currentThread().getName() + " waiting at barrier 2"); this.barrier2.await(); System.out.println(Thread.currentThread().getName() + " done!"); } catch (InterruptedException e) { e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } } |
Runnable barrier1Action = new Runnable() { public void run() { System.out.println("BarrierAction 1 executed "); } }; Runnable barrier2Action = new Runnable() { public void run() { System.out.println("BarrierAction 2 executed "); } }; CyclicBarrier barrier1 = new CyclicBarrier(2, barrier1Action); CyclicBarrier barrier2 = new CyclicBarrier(2, barrier2Action); CyclicBarrierRunnable barrierRunnable1 = new CyclicBarrierRunnable(barrier1, barrier2); CyclicBarrierRunnable barrierRunnable2 = new CyclicBarrierRunnable(barrier1, barrier2); new Thread(barrierRunnable1).start(); new Thread(barrierRunnable2).start(); |
Exchanger
Exchanger: 用于两个线程之间交换元素。
Exchanger exchanger = new Exchanger(); //两个线程内调用exchanger.exchange(object)方法提供自身元素,交换获取得到另一//个线程的元素 Object previous = this.object; this.object = this.exchanger.exchange(this.object); |
Semaphore
Semaphore:用于对临界资源进行保护以及在线程总进行信号传递。信号的获取必须有空闲信号或者已占用信号的线程释放信号。等待线程可以是按照公平方式等待,也可以是不公平的。 new Semaphore(1,true);
Semaphore semaphore = new Semaphore(1); //critical section semaphore.acquire(); ... semaphore.release(); //acquire和release在不同线程中使用可以用于信号传递 |