This commit is contained in:
xiongraorao 2018-08-06 21:34:13 +08:00
commit 4ab3390a38
18 changed files with 838 additions and 0 deletions

View File

@ -0,0 +1,31 @@
package com.raorao;
/**
* .
*
* @author Xiong Raorao
* @since 2018-08-02-16:46
*/
public class Test {
private int a;
public static void main(String[] args) {
//System.out.println(foo());
int r = new Test().foo();
System.out.println(r);
}
public int foo() {
try {
System.out.println("sadfasdfasdf");
return a;
} catch (Exception e) {
e.printStackTrace();
return 3;
} finally {
System.out.println("finally: " + ++a);
return a;
}
}
}

View File

@ -0,0 +1,28 @@
package com.raorao.java.base;
/**
* 内部类的引用.
*
* @author Xiong Raorao
* @since 2018-08-06-14:43
*/
public class InnerClassTest {
void f(){
System.out.println("InnerClassTest.f()");
}
public class Inner{
public InnerClassTest outer(){
return InnerClassTest.this;
}
}
public Inner inner(){
return new Inner();
}
public static void main(String[] args) {
InnerClassTest test = new InnerClassTest();
InnerClassTest.Inner inner = test.new Inner();
//inner = new InnerClassTest.Inner(); // 如果Inner 是static就可以否则只能采用上面的语句
}
}

View File

@ -0,0 +1,65 @@
package com.raorao.java.thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 可重入锁测试.
*
* @author Xiong Raorao
* @since 2018-08-06-10:27
*/
public class ReentrantLockTest {
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
ReentrantLockTest test = new ReentrantLockTest();
new Thread(() -> test.testLock()).start();
new Thread(() -> test.testLock()).start();
Thread t = new Thread(() -> test.awaitA());
t.start();
Thread.sleep(2000);
test.signalA();
}
public void awaitA() {
lock.lock();
try {
System.out.println("before awaitA at " + System.currentTimeMillis());
conditionA.await(); // 在此之前必须获得锁不然报错illegalMonitorStateException 错误
System.out.println("after awaitA at " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println(" 释放锁 awaitA ");
}
}
public void signalA() {
lock.lock();
try {
System.out.println("signalA at " + System.currentTimeMillis());
conditionA.signal(); // 在此之前必须获得锁不然报错illegalMonitorStateException 错误
System.out.println("signalA over at " + System.currentTimeMillis());
} finally {
lock.unlock();
System.out.println(" 释放锁 signalA ");
}
}
public void testLock() {
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.print(i + " ");
}
System.out.println();
lock.unlock();
}
}

View File

@ -0,0 +1,68 @@
package com.raorao.java.thread;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 读写锁测试.
*
* @author Xiong Raorao
* @since 2018-08-06-11:48
*/
public class ReentrantReadWriteLockTest {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read(){
lock.readLock().lock(); // 读锁
System.out.println("获得读锁 " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.readLock().unlock();
}
}
public void write(){
lock.writeLock().lock(); // 写锁
System.out.println("获得写锁 " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.writeLock().unlock();
}
}
public static void main(String[] args) {
// 1. 读读共享, A B 同时获得锁
ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();
Thread t1 = new Thread(()-> {
Thread.currentThread().setName("A");
test.read();
});
Thread t2 = new Thread(()-> {
Thread.currentThread().setName("B");
test.read();
});
t1.start();
t2.start();
// 2. 写写互斥, D线程比C线程落后两秒执行
t1 = new Thread(()->{
Thread.currentThread().setName("C");
test.write();
});
t2 = new Thread(()->{
Thread.currentThread().setName("D");
test.write();
});
t1.start();
t2.start();
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2018. Xiong Raorao. All rights reserved.
* Project Name: book-notes
* File Name: Test.java
* Date: 18-7-25 下午5:32
* Author: Xiong Raorao
*/
package com.raorao.java.thread;
/**
* .
*
* @author Xiong Raorao
* @since 2018-07-25-17:32
*/
public class ThreadLocalTest {
private static ThreadLocal<Integer> local = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
System.out.println(" I am t1");
local.set(1);
try {
Thread.sleep(2000);
System.out.println("t1 value: " + local.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread.sleep(2000);
Thread t2 = new Thread(() -> {
System.out.println("I am t2");
System.out.println("before set , I get " + local.get());
try {
Thread.sleep(2000);
local.set(2);
System.out.println("set after 2 s, I get " + local.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t2.start();
t1.start();// 无论怎么更换两个线程的启动顺序得到的值是不一样的
}
}

View File

@ -0,0 +1,36 @@
package com.raorao.java.thread;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* 定时器.
*
* @author Xiong Raorao
* @since 2018-08-06-13:07
*/
public class TimerTest {
private static Timer timer = new Timer();
static class MyTask extends TimerTask{
@Override
public void run() {
System.out.println("运行时间: " + new Date());
}
}
public static void main(String[] args) {
MyTask task1 = new MyTask();
try {
Date taskDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2018-08-06 13:15:00");
System.out.println("执行时间: " + taskDate.toLocaleString() + ",当前时间" + new Date().toLocaleString());
timer.schedule(task1, taskDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
}

View File

@ -28,11 +28,13 @@ Thoutworks | 内推 | | [内推链接](https://jinshuju.net/f/CcO2JA)
顺丰科技 | 网申 | 即日 -- 9.23日 | [招聘官网](http://campus.sf-tech.com.cn/campusRecruitment/Default.html?p=28668990421) <br>7月20日投了内推
多益网络 | 内推 | <li>内推笔试第一批8.11 10:00 <li> 内推笔试第二批: 9.06 10:00 | [招聘官网](https://xz.duoyi.com/jobs/index.html?t=0) <br>7月20日投了内推
好未来 | 提前批 | 8.19日截止 | [招聘官网](http://job.100tal.com/jobxq?jobId=510212759) <li> 7月24日投了
华为 | 网申 | | [招聘官网](http://career.huawei.com/reccampportal/next/mini/index.html)
腾讯 | 提前批/网申 | <li> 提前批7.25-9.12 <li> 提前批7.25-9.14 <li> 在线笔试9.16-9.17 <li> 面试9.26开始| [招聘官网](https://join.qq.com/)
抖音、头条 | 内推 | 8.1 - 12.31| [招聘官网](https://job.bytedance.com/campus/) <li> 8.2 投简历
携程 | 内推 | <li> 内推8.2 - 8.12 <li> 网申 8.2 - 9.4 | [招聘官网](http://campus.ctrip.com)
老虎证券 | 内推 | <li> 内推: 8.4 - 8.10 | <li>8.4 日已经提交内推
贝壳网 | 内推 | | [招聘官网](http://campus.ke.com/)<li> 8.4已投简历
美团 | 内推/网申 | 面试时间9.6-9.14 | <li>8.6 已投简历
## 2. 面试记录

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -16,6 +16,28 @@
- [newCachedThreadPool](#newcachedthreadpool)
- [Future 接口](#future-接口)
- [ScheduledThreadPoolExecutor](#scheduledthreadpoolexecutor)
- [ThreadLocal](#threadlocal)
- [Lock](#lock)
- [Synchronized](#synchronized)
- [ReentrantLock](#reentrantlock)
- [ReentranceLock 几个特殊的方法](#reentrancelock-几个特殊的方法)
- [ReentranceReadWriteLock](#reentrancereadwritelock)
- [condition](#condition)
- [公平锁和非公平锁](#公平锁和非公平锁)
- [Timer](#timer)
- [shedule(TimerTask task, Date date)](#sheduletimertask-task-date-date)
- [shedule 周期性执行](#shedule-周期性执行)
- [sheduleAtFixedRate](#sheduleatfixedrate)
- [Concurrent 容器](#concurrent-容器)
- [BlockingQueue](#blockingqueue)
- [DelayQueue](#delayqueue)
- [PriorityBlockingQueue](#priorityblockingqueue)
- [ArrayBlockingQueue 和 LinkedBlockingQueue](#arrayblockingqueue-和-linkedblockingqueue)
- [ConcurrentHashMap](#concurrenthashmap)
- [ConcurrentLinkedDeque 和 ConcurrentLinkedQueue](#concurrentlinkeddeque-和-concurrentlinkedqueue)
- [Deque](#deque)
- [LinkedList](#linkedlist)
- [ArrayDeque](#arraydeque)
- [参考文档](#参考文档)
<!-- /TOC -->
@ -475,6 +497,547 @@ ScheduledThreadPoolExecutor 继承自 ThreadPoolExecutor, 主要用来在给定
该类采用了DelyQueue封装了一个优先队列该队列会对队列中的SheduledFutureTask 进行排序。time小的会排在前面如果time相同则会比较sequenceNumber, 就是说如果两个任务的执行时间相同,谁先提交就谁先执行
# ThreadLocal
变量值的共享可以采用public static 的类变量但是在多线程情况下static 类变量显然不能满足多线程的读写因此采用ThreadLocal 变量来存储多线程下的变量的副本。
``` java
/*
* Copyright (c) 2018. Xiong Raorao. All rights reserved.
* Project Name: book-notes
* File Name: Test.java
* Date: 18-7-25 下午5:32
* Author: Xiong Raorao
*/
package com.raorao.java.thread;
/**
* .
*
* @author Xiong Raorao
* @since 2018-07-25-17:32
*/
public class ThreadLocalTest {
private static ThreadLocal<Integer> local = new ThreadLocal<>();
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(() -> {
System.out.println(" I am t1");
local.set(1);
try {
Thread.sleep(2000);
System.out.println("t1 value: " + local.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread.sleep(2000);
Thread t2 = new Thread(() -> {
System.out.println("I am t2");
System.out.println("before set , I get " + local.get());
try {
Thread.sleep(2000);
local.set(2);
System.out.println("set after 2 s, I get " + local.get());
} catch (InterruptedException e) {
e.printStackTrace();
}
});
t2.start();
t1.start();// 无论怎么更换两个线程的启动顺序,得到的值是不一样的
}
}
```
# Lock
除了使用synchronized 关键字加锁同步之外也可以实现Lock 来自定义同步过程。
## Synchronized
jvm提供的一种互斥同步锁的方式
synchronized 可以作用于代码块,方法,类方法,类等,锁加载的
## ReentrantLock
``` java
public class LockExample {
private Lock lock = new ReentrantLock();
public void func() {
lock.lock();
try {
for (int i = 0; i < 10; i++) {
System.out.print(i + " ");
}
} finally {
lock.unlock(); // 确保释放锁,从而避免发生死锁。
}
}
public static void main(String[] args) {
LockExample lockExample = new LockExample();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> lockExample.func());
executorService.execute(() -> lockExample.func());
}
}
```
输出:
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9
**synchronized 和 ReentrantLock的比较**
1. 锁的实现
synchronized 是 JVM 实现的,而 ReentrantLock 是 JDK 实现的。
2. 性能
新版本 Java 对 synchronized 进行了很多优化例如自旋锁等synchronized 与 ReentrantLock 大致相同。
3. 等待可中断
当持有锁的线程长期不释放锁的时候,正在等待的线程可以选择放弃等待,改为处理其他事情。
ReentrantLock 可中断,而 synchronized 不行。
4. 公平锁
公平锁是指多个线程在等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁。
synchronized 中的锁是非公平的ReentrantLock 默认情况下也是非公平的,但是也可以是公平的。
5. 锁绑定多个条件
一个 ReentrantLock 可以同时绑定多个 Condition 对象。
### ReentranceLock 几个特殊的方法
getHoldCount(): 查询当前线程保持此锁的个数
getQueueLength(): 返回正在等待获取次锁定的估计线程数。比如有5个线程其中1个线程执行await()方法,调用该方法就返回4
getWaitQueueLength(): 返回等待与此锁定相关的给定条件Condition的线程估计数。
hasQueuedThread(Thread t): 查询指定线程是否正在等待获取此锁定
hasQueuedThreads(): 查询是否有线程正在等待获取此锁定
hasWaiters(Condition condition): 查询是否有线程正在等待与次锁定有关的condition条件
## ReentranceReadWriteLock
ReentranceLock 是完全互斥锁同一时间只有同一个线程在执行ReentrantLock.lock()后面的任务,虽然安全,但是效率低下。
ReentranceReadWriteLock读写锁读锁是共享锁多个读锁之间不互斥读锁和写锁之间互斥写锁和写锁之间互斥。
``` java
package com.raorao.java.thread;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* 读写锁测试.
*
* @author Xiong Raorao
* @since 2018-08-06-11:48
*/
public class ReentrantReadWriteLockTest {
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public void read(){
lock.readLock().lock(); // 读锁
System.out.println("获得读锁 " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.readLock().unlock();
}
}
public void write(){
lock.writeLock().lock(); // 写锁
System.out.println("获得写锁 " + Thread.currentThread().getName() + " " + System.currentTimeMillis());
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.writeLock().unlock();
}
}
public static void main(String[] args) {
// 1. 读读共享, A 和 B 同时获得锁
ReentrantReadWriteLockTest test = new ReentrantReadWriteLockTest();
Thread t1 = new Thread(()-> {
Thread.currentThread().setName("A");
test.read();
});
Thread t2 = new Thread(()-> {
Thread.currentThread().setName("B");
test.read();
});
t1.start();
t2.start();
// 2. 写写互斥, D线程比C线程落后两秒执行
t1 = new Thread(()->{
Thread.currentThread().setName("C");
test.write();
});
t2 = new Thread(()->{
Thread.currentThread().setName("D");
test.write();
});
t1.start();
t2.start();
}
}
```
读写和写读两个锁也是互斥的,这里就不测试了。
## condition
condition 可以用于实现线程wait 和 notify主要的方法有await()、signal() 和 signalAll() 方法对应Object 类的 wait(), notify() 和notifyAll()方法,区别是,**前者只会通知持有锁的在等待的对象,后者则是对所有等待的线程通知,效率低下**
``` java
package com.raorao.java.thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/**
* 可重入锁测试.
*
* @author Xiong Raorao
* @since 2018-08-06-10:27
*/
public class ReentrantLockTest {
private Lock lock = new ReentrantLock();
private Condition conditionA = lock.newCondition();
private Condition conditionB = lock.newCondition();
public static void main(String[] args) throws InterruptedException {
ReentrantLockTest test = new ReentrantLockTest();
new Thread(() -> test.testLock()).start();
new Thread(() -> test.testLock()).start();
Thread t = new Thread(() -> test.awaitA());
t.start();
Thread.sleep(2000);
test.signalA();
}
public void awaitA() {
lock.lock();
try {
System.out.println("before awaitA at " + System.currentTimeMillis());
conditionA.await(); // 在此之前必须获得锁不然报错illegalMonitorStateException 错误
System.out.println("after awaitA at " + System.currentTimeMillis());
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
System.out.println(" 释放锁 awaitA ");
}
}
public void signalA() {
lock.lock();
try {
System.out.println("signalA at " + System.currentTimeMillis());
conditionA.signal(); // 在此之前必须获得锁不然报错illegalMonitorStateException 错误
System.out.println("signalA over at " + System.currentTimeMillis());
} finally {
lock.unlock();
System.out.println(" 释放锁 signalA ");
}
}
public void testLock() {
lock.lock();
for (int i = 0; i < 5; i++) {
System.out.print(i + " ");
}
System.out.println();
lock.unlock();
}
}
```
上面的程序对应的是利用Condition的进行等待和通知。
## 公平锁和非公平锁
公平锁线程获取锁的顺序使按照线程加锁的顺序来分配的满足FIFO
非公平锁:等待线程抢占获取锁,也有可能造成某个线程一直获取不到锁
ReentrantLock 构造函数输入可以设置是否是公平锁,默认非公平锁。
# Timer
Timer 定时器,主要负责计划任务的功能,也就是在指定的时间开始执行某一个任务。
## shedule(TimerTask task, Date date)
``` java
package com.raorao.java.thread;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
* 定时器.
*
* @author Xiong Raorao
* @since 2018-08-06-13:07
*/
public class TimerTest {
private static Timer timer = new Timer();
static class MyTask extends TimerTask{
@Override
public void run() {
System.out.println("运行时间: " + new Date());
}
}
public static void main(String[] args) {
MyTask task1 = new MyTask();
try {
Date taskDate = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse("2018-08-06 13:15:00");
System.out.println("执行时间: " + taskDate.toLocaleString() + ",当前时间" + new Date().toLocaleString());
timer.schedule(task1, taskDate);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
```
输出:
执行时间: 2018-8-6 13:15:00当前时间2018-8-6 13:14:27
运行时间: Mon Aug 06 13:15:00 CST 2018
如果任务执行时间比当前时间晚,则到了计划时间执行,否则立即执行。
## shedule 周期性执行
函数: shedule(TimeTask task, Date firstTime, long period)
表示在指定的日期之后,按照指定的时间间隔(period)周期性的无休止的执行某一任务。
**同样满足如果是未来的任务,到计划时间执行,否则立即执行**
## sheduleAtFixedRate
该方法和shedule方法的区别在于任务不延迟的情况。
shedule: 如果执行任务的时间没有被延迟,那么下一次任务的执行时间参考的是上一次任务的“开始”时间计算。
sheduleAtFixedRate: 如果执行任务的时间没有被延迟,那么下一次任务的执行时间参考的是上一次任务的“结束”时间计算。
# Concurrent 容器
## BlockingQueue
![](img/TIM截图20180806153217.jpg)
BlockingQueue 是一个阻塞接口,定义了阻塞队列的行为。
- boolean add(E e): 对尾插入元素成功返回true;
- boolean offer(E e): 队尾插入元素成功返回true; 和 add 区别在于,如果超过队列容量add 会抛出 IllegalStateException 异常
- void put(E e): 队尾插入元素,如果在线程等待的时候发生线程中断,抛出异常。
- boolean offer(E e, long timeout, TimeUnit unit): 超时放弃,线程等待的时候如果发生中断信号,也会抛出中断异常。
- E take(): 弹出队头元素,线程等待的时候如果发生中断信号,也会抛出中断异常。
- E remove(): 弹出队头元素, 如果为空抛出NoSuchElementException;
- E poll(): 弹出队头元素如果为空返回null
- E poll(long timeout, TimeUnit unit): 超时放弃,线程等待的时候如果发生中断信号,抛出异常。
- E element(): 仅仅返回对头元素, 如果为空抛出NoSuchElementException;
- E peek(): 仅仅返回队头元素如果为空返回null
- int remainingCapacity(): 返回理想情况下,可以直接入队不用阻塞的元素个数
## DelayQueue
![](img/TIM截图20180806160547.jpg)
无界的阻塞队列(BlockingQueue), 用于防止实现了Delayed接口的对象,其中的对象只能在到期时才能从对队列中取走。队列本身是有序的, 即对头对象的延迟到期的时间最长的Delayed元素。
为了具有调用行为存放到DelayDeque的元素必须继承Delayed接口。Delayed接口使对象成为延迟对象它使存放在DelayQueue类中的对象具有了激活日期。该接口强制执行下列两个方法。
CompareTo(Delayed o)Delayed接口继承了Comparable接口因此有了这个方法。
getDelay(TimeUnit unit):这个方法返回到激活日期的剩余时间,时间单位由单位参数指定。
``` java
public class DelayEvent implements Delayed {
private Date startDate;
public DelayEvent(Date startDate) {
super();
this.startDate = startDate;
}
@Override
public int compareTo(Delayed o) {
long result = this.getDelay(TimeUnit.NANOSECONDS)
- o.getDelay(TimeUnit.NANOSECONDS);
if (result < 0) {
return -1;
} else if (result > 0) {
return 1;
} else {
return 0;
}
}
@Override
public long getDelay(TimeUnit unit) {
Date now = new Date();
long diff = startDate.getTime() - now.getTime();
return unit.convert(diff, TimeUnit.MILLISECONDS);
}
}
public class DelayTask implements Runnable {
private int id;
private DelayQueue<DelayEvent> queue;
public DelayTask(int id, DelayQueue<DelayEvent> queue) {
super();
this.id = id;
this.queue = queue;
}
@Override
public void run() {
Date now = new Date();
Date delay = new Date();
delay.setTime(now.getTime() + id * 1000); // 根据id的不同延迟的时间不同
System.out.println("Thread " + id + " " + delay);
for (int i = 0; i < 100; i++) {
DelayEvent delayEvent = new DelayEvent(delay);
queue.add(delayEvent);
}
}
}
public class DelayDequeMain {
public static void main(String[] args) throws Exception {
DelayQueue<DelayEvent> queue = new DelayQueue<DelayEvent>();
Thread threads[] = new Thread[5];
for (int i = 0; i < threads.length; i++) {
DelayTask task = new DelayTask(i + 1, queue);
threads[i] = new Thread(task);
}
for (int i = 0; i < threads.length; i++) {
threads[i].start();
}
for (int i = 0; i < threads.length; i++) {
try {
threads[i].join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
do {
int counter = 0;
DelayEvent delayEvent;
do {
delayEvent = queue.poll();
if (delayEvent != null) {
counter++;
}
} while (delayEvent != null);
System.out.println("At " + new Date() + " you have read " + counter+ " event");
TimeUnit.MILLISECONDS.sleep(500);
} while (queue.size() > 0);
}
}
```
## PriorityBlockingQueue
![](img/TIM截图20180806160740.jpg)
阻塞的优先队列。
## ArrayBlockingQueue 和 LinkedBlockingQueue
![](img/TIM截图20180806162223.jpg)
![](img/TIM截图20180806162336.jpg)
FIFO 阻塞队列, 前者采用固定数组长度的数组实现队列(初始化需指定队列长度),后者采用链表实现。
## ConcurrentHashMap
![](img/TIM截图20180806163031.jpg)
ConcurrentHashMap 默认容量为16 最大容量2^30默认并发度16负载因子0.75。当散列桶的元素个数超过8的时候将链表改为红黑树jdk1.8)。
ConcurrentHashMap 相较于HashMap采用了分段锁Segment, 继承自 ReentrantLock的方式保证多线程安全JDK1.7)。
在JDK1.8 中, CAS 操作来支持更高的并发度,在 CAS 操作失败时使用内置锁 synchronized
## ConcurrentLinkedDeque 和 ConcurrentLinkedQueue
![](img/TIM截图20180806164620.jpg)
![](img/TIM截图20180806164709.jpg)
ConcurrentLinkedDeque: 线程安全的链表实现的双端队列。
ConcurrentLinkedQueque: 线程安全的链表实现的队列。
## Deque
Deque 定义一个双端队列的接口,可以在两段进行插入和弹出, 方法如下:
修饰符和返回值 | 方法名 | 描述
--- | --- | ---
void | push(E) |向队列头部插入一个元素,失败时抛出异常
void | addFirst(E) |向队列头部插入一个元素,失败时抛出异常
void | addLast(E) |向队列尾部插入一个元素,失败时抛出异常
boolean | offerFirst(E)|向队列头部加入一个元素,失败时返回false
boolean | offerLast(E)|向队列尾部加入一个元素,失败时返回false
E | getFirst() | 获取队列头部元素,队列为空时抛出异常
E | getLast() | 获取队列尾部元素,队列为空时抛出异常
E | peekFirst() | 获取队列头部元素,队列为空时返回null
E | peekLast() | 获取队列尾部元素,队列为空时返回null
boolean | removeFirstOccurrence(Object) | 删除第一次出现的指定元素,不存在时返回false
boolean | removeLastOccurrence(Object) | 删除最后一次出现的指定元素,不存在时返回false
E | pop() | 弹出队列头部元素,队列为空时抛出异常
E | removeFirst() | 弹出队列头部元素,队列为空时抛出异常
E | removeLast() | 弹出队列尾部元素,队列为空时抛出异常
E | pollFirst() | 弹出队列头部元素,队列为空时返回null
E | pollLast() | 弹出队列尾部元素,队列为空时返回null
Iterator<E> | descendingIterator() | 返回队列反向迭代器
### LinkedList
![](img/TIM截图20180806171115.jpg)
LinkedList: 链表实现的双端队列
### ArrayDeque
![](img/TIM截图20180806171310.jpg)
ArrayDeque: 数组实现的双端队列默认队列长度为16队列满了就直接扩充一倍double
# 参考文档
- [java并发编程--Executor框架](https://www.cnblogs.com/MOBIN/p/5436482.html)