1. ConcurrentHashMap
* 本方法测试点(基于jdk1.8):
* ConcurrentHashMap
* ConcurrentSkipListMap
* Hashtable
* HashMap
* 执行时间对比,Map<String,String> 而Set<String>同理
* 理解:
* SkipList跳表
* 用CountDownLatch统计多线程执行
package container_test;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
import java.util.concurrent.CountDownLatch;
/**
*
* 本方法测试点(基于jdk1.8):
* ConcurrentHashMap
* ConcurrentSkipListMap
* Hashtable
* HashMap
* 执行时间对比
* Map<String,String> 而Set<String>同理
*
* 理解:
* SkipList跳表
* 用CountDownLatch统计多线程执行时间
*
* @author x1c
*/
public class ConcurrentMapTest {
public static void main(String[] args) {
// Map<String, String> map = new ConcurrentHashMap<>(); //多线程执行总时间:76ms 94ms 141ms 203ms 188ms 94ms 79ms
//高并发并且排序
// Map<String, String> map = new ConcurrentSkipListMap<>(); //多线程执行总时间:78ms 79ms 188ms 437ms 79ms 266ms 70ms
//HashTable默认实现都带锁 效率较低
// Map<String, String> map = new Hashtable<>(); //多线程执行总时间:117ms 141ms 79ms 78ms 78ms 78ms 125ms
Map<String, String> map = new HashMap<>(); //多线程执行总时间:109ms 94ms 110ms 79ms 79ms 78ms 78ms
//Collections.synchronizedMap(map);
//treeMap
Random random = new Random();
Thread[] threads = new Thread[100]; //100个线程
/**
* Constructs a {@code CountDownLatch} initialized with the given count.
* count the number of times {@link #countDown} must be invoked
* before threads can pass through {@link #await}
*/
CountDownLatch latch = new CountDownLatch(threads.length);
long start = System.currentTimeMillis();
for (int i = 0; i < threads.length; i++) {
threads[i] = new Thread(()->{
for (int j = 0; j < 100000; j++) {
map.put("key"+random.nextInt(100000), "b"+random.nextInt(100000));
latch.countDown(); //sync.releaseShared(1);
}
}
);
}
Arrays.asList(threads).forEach(tt->tt.start()); //依次启动线程
try {
/**
* Causes the current thread to wait until the latch has counted down to
* zero, unless the thread is {@linkplain Thread#interrupt interrupted}.
*/
latch.await();//门闩为0 唤醒
} catch (InterruptedException e) {
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.err.println("多线程执行总时间:"+(end -start)+"ms");
}
}
CountHashMap 分段锁 16段
private static final int DEFAULT_CAPACITY = 16;
多线程执行ConcurrentHashMap总体较高!线程安全!
2.CopyOnWrite
* 写时复制容器 CopyOnWrite
* 多线程环境下,写时效率低,读时效率高
* 适合写少读多的环境
* 实际使用场合:如事件监听器
package container_test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* 写时复制容器 CopyOnWrite
* 多线程环境下,写时效率低,读时效率高
* 适合写少读多的环境
* 实际使用场合:如事件监听器
* @author x1c
*
*/
public class CopyOnWriteList {
public static void main(String[] args) {
//ArrayList会有并发问题
List<String> lists = new ArrayList<>(); //private static final int DEFAULT_CAPACITY = 10;
// List<String> lists = new Vector<>(); //this(10);
// List<String> lists = new CopyOnWriteArrayList<>();
Random random = new Random();
Thread[] threads = new Thread[100];
for (int i = 0; i < threads.length; i++) {
Runnable task = new Runnable() {
@Override
public void run() {
for (int j = 0; j < 1000; j++) {
lists.add("a"+random.nextInt(1000));
}
}
};
threads[i] = new Thread(task);
}
runAndComputeTime(threads); //计算各个线程执行总时间
System.out.println("list.size:"+lists.size());
}
static void runAndComputeTime(Thread[] threads) {
long start = System.currentTimeMillis();
Arrays.asList(threads).forEach(tt->tt.start()); //各个线程启动
Arrays.asList(threads).forEach(tt->{
try {
tt.join(); //Waits for this thread to die.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
);
long end = System.currentTimeMillis();
System.err.println("线程执行总时间:"+(end - start)+"ms");
}
}
/**
* 测试结果:
* CopyOnWriteList
* 线程执行总时间:4626ms
list.size:100000
Vector(加了锁)
线程执行总时间:169ms
list.size:100000
ArrayList
线程执行总时间:138ms
list.size:97588
*/
3. SynchronizedList
list实现加锁
package container_test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* list实现加锁
*
* @author x1c
*
*/
public class SynchronizedList {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
List<String> synchronizedList = Collections.synchronizedList(list); //已经加锁
}
}
4.ConcurrentLinkedQueue
无界队列
package container_test;
import java.util.Deque;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
/**
* ConcurrentQueue
* 重要且经常用!
* 游戏消息同步:queue+threadPool
*
* @author x1c
*
*/
public class ConcurrentQueue {
public static void main(String[] args) {
Queue<String> strs = new ConcurrentLinkedQueue<>(); //ConcurrentLinkedQueue 无界队列
for (int i = 0; i < 10; i++) {
// boolean java.util.Queue.offer(String e)
strs.offer("a"+i); //offer
}
System.out.println(strs);
System.out.println(strs.size());
/**
* Retrieves and removes the head of this queue,
* or returns {@code null} if this queue is empty.
*/
System.out.println(strs.poll()); //拿出使用并删除
System.out.println(strs.size());
System.out.println(strs.peek()); //拿出使用而不删除
System.out.println(strs.size());
//双端队列Deque 详见javaAPI
// Deque<E>
}
}
5.LinkedBlockingQueue
* LinkedBlockingQueue
* 阻塞式无界队列
package container_test;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* LinkedBlockingQueue
* 阻塞式无界队列
* @author x1c
*
*/
public class T05_LinkedBlockingQueue {
static BlockingQueue<String> strs = new LinkedBlockingQueue<>(); //阻塞式无界队列
static Random random = new Random();
public static void main(String[] args) {
//生产者
new Thread(()->{
for (int i = 0; i < 10; i++) {
try {
strs.put("a"+random.nextInt(1000)); //如果满了,就会等待
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
TimeUnit.MILLISECONDS.sleep(random.nextInt(1000)); //如果空了,就会等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
,"p1").start();
//消费者
for (int i = 0; i < 10; i++) {
new Thread(()->{
try {
System.out.println(Thread.currentThread().getName()+"--take--" + strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
).start();
}
}
}
6.ArrayBlockingQueue
* ArrayBlockingQueue
* 阻塞式有界队列
package container_test;
import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
/**
* ArrayBlockingQueue
* 阻塞式有界队列
* @author x1c
*
*/
public class T05_ArrayBlockingQueue {
static BlockingQueue<String> strs = new ArrayBlockingQueue<>(10); //阻塞式有界队列
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
strs.add("a"+i);
}
try {
strs.put("111111"); //阻塞
} catch (InterruptedException e) {
e.printStackTrace();
}
// strs.offer("111111"); //false
// try {
// strs.offer("1111111", 1000, TimeUnit.MICROSECONDS); //false
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// strs.add("111111");
System.out.println(strs);
}
}
7.DelayQueue
* DelayQueue
* 无界队列
* 插入有序 等待时间最长的元素先被消费
* 场景:定时任务
package container_test;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
/**
* DelayQueue
* 无界队列
* 插入有序 等待时间最长的元素先被消费
*
* 场景:定时任务
*
* @author x1c
*
*/
public class T07_DelayQueue {
static BlockingQueue<Mytask> tasks = new DelayQueue<>(); //DelayQueue 元素要实现Delayed接口
//interface Delayed extends Comparable
//DelayQueue<E extends Delayed> extends AbstractQueue<E>
static class Mytask implements Delayed{
long runingTime;
public Mytask(long runingTime) {
this.runingTime = runingTime;
}
@Override
public int compareTo(Delayed o) {
if (this.getDelay(TimeUnit.MILLISECONDS) < o.getDelay(TimeUnit.MILLISECONDS)) {
return -1;
}else if(this.getDelay(TimeUnit.MILLISECONDS) > o.getDelay(TimeUnit.MILLISECONDS)) {
return 1;
}else {
return 0;
}
}
@Override
public long getDelay(TimeUnit unit) {
return unit.convert(runingTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
}
@Override
public String toString() {
return "Mytask [runingTime=" + runingTime + "]";
}
}
public static void main(String[] args) throws InterruptedException {
long now = System.currentTimeMillis();
Mytask t1 = new Mytask(now + 1000);
Mytask t2 = new Mytask(now + 2000);
Mytask t3 = new Mytask(now + 3000);
Mytask t4 = new Mytask(now + 4000);
Mytask t5 = new Mytask(now + 50);
tasks.put(t1); //DelayQueue<E extends Delayed> extends AbstractQueue<E>
tasks.put(t2);
tasks.put(t3);
tasks.put(t4);
tasks.put(t5);
System.out.println(tasks);
for (int i = 0; i < 5; i++) {
System.out.println(tasks.take());
}
}
}
8.TransferQueue
* TransferQueue
* 不放入队列,直接给消费者线程,若无消费者阻塞
* 场景:实时系统消息同步,提高并发 如netty框架用的比较多
package container_test;
import java.util.concurrent.LinkedTransferQueue;
/**
* TransferQueue
* 不放入队列,直接给消费者线程,若无消费者阻塞
*
* 场景:实时系统消息同步,提高并发 如netty框架用的比较多
*
* @author x1c
*
*/
public class T08_TransferQueue {
public static void main(String[] args) {
LinkedTransferQueue<String> strs = new LinkedTransferQueue(); //LinkedTransferQueue
//消费者线程 先
new Thread(()->{
try {
System.out.println(strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
).start();
try {
strs.transfer("111");
} catch (InterruptedException e1) {
e1.printStackTrace();
}
//消费者线程
// new Thread(()->{
// try {
// System.out.println(strs.take());
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
// ).start();
}
}
9.SynchronousQueue
* SynchronousQueue
* 同步队列
* 容量为0
package container_test;
import java.util.concurrent.LinkedTransferQueue;
import java.util.concurrent.SynchronousQueue;
/**
* SynchronousQueue
* 同步队列
* 容量为0
*
* @author x1c
*
*/
public class T09_SynchronousQueue {
public static void main(String[] args) {
SynchronousQueue<String> strs = new SynchronousQueue(); //LinkedTransferQueue
//消费者线程 先
new Thread(()->{
try {
System.out.println(strs.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
).start();
try {
strs.put("111"); //阻塞等待消费者消费
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(strs.size());
}
}
小结:
---------------------------------------------------------------------------
1.Map/Set
HashMap
TreeMap (SortMap接口,基于红黑树,默认按键的升序排序 )
LinkedHashMap
并发较小:
Hashtable
Collections.synchronizedXXX
高并发:
ConcurrentHashMap
ConcurrentSkipList 跳表 有序
----------------------------------------------------------------------------
2. List
不同步:
ArrayList
LinkedList
同步:
Vector
Collections.synchronizedXXX
CopyOnWriteList 写时复制,写少读多时效率高 不需要加锁 因为不存在脏读可能
--------------------------------------------------------------------------------
3. Queue
ConcurrentLinkedQueue 高并发
BlockingQueue 阻塞式队列
LinkedBlockingQueue 无界队列
ArrayBlockingQueue 有界队列
TransferQueue 直接给消费者线程 否则阻塞
SynchronousQueue 特殊的TransferQueue 容量为0
DelayQueue 执行定时任务
--------------------------------------------------------------------------------------