常见的非阻塞队列
1) ConcurrentHashMap
2) ConcurrentSkipListMap
3) ConcurrentSkipListSet
4) ConcurrentLinkedQueue
5) ConcurrentLinkedDeque
6) CopyOnWriteArrayList
7) CopyOnWriteArraySet
HashTable、Vector调用iterator()方法返回Iterator对象后,再调用remove()时会出现ConcurrentModificationException异常,也就是并不支持Iterator并发的删除。
- ConcurrentHashMap是 弱一致性模型
- ConcurrentSkipListMap 并发程序中可以保证顺序
public class MyService {
public ConcurrentSkipListMap map = new ConcurrentSkipListMap();
public MyService(){
UserInfo user1 = new UserInfo(1, "user1");
UserInfo user2 = new UserInfo(2, "user2");
UserInfo user3 = new UserInfo(3, "user3");
UserInfo user4 = new UserInfo(4, "user4");
UserInfo user5 = new UserInfo(5, "user5");
map.put(user1, "value1");
map.put(user4, "value4");
map.put(user2, "value2");
map.put(user5, "value5");
map.put(user3, "value3");
}
}
public class ThreadA extends Thread {
private MyService myservice;
public ThreadA(MyService myservice){
this.myservice = myservice;
}
@Override
public void run() {
while(!myservice.map.isEmpty()){
Map.Entry entry = myservice.map.pollFirstEntry();
UserInfo userInfo = (UserInfo) entry.getKey();
System.out.println("key = " + userInfo.getId() + entry.getValue());
}
}
}
- ConcurrentSkipListSet 支持排序且不允许重复的元素
ConcurrentLinkedQueue 提供了并发环境的队列操作
方法poll当没有获得数据时返回null,如果有数据则移除表头,并将表头进行返回
方法element当没有数据时,出现NoSuchElementExcepiton异常,如果有数据则返回表头项
方法peek当没有数据时返回null,有数据则不移除表头,返回表头项ConcurrentLinkedDeque
public class AddTask implements Runnable {
private ConcurrentLinkedDeque<String> list;
public AddTask(ConcurrentLinkedDeque<String> list){
this.list = list;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
for(int i=0;i<1000;i++){
list.add(name+"--" + (i+1));
}
}
}
public class RemoveTask implements Runnable{
private ConcurrentLinkedDeque list;
public RemoveTask(ConcurrentLinkedDeque list){
this.list = list;
}
@Override
public void run() {
String name = Thread.currentThread().getName();
for(int i=0;i<500;i++){
list.pollFirst();
list.pollLast();
}
}
}
public class Main {
public static void main(String[] args) throws InterruptedException {
ConcurrentLinkedDeque<String> list = new ConcurrentLinkedDeque<>();
Thread[] threads = new Thread[100];
for(int i=0;i<threads.length;i++){
AddTask task = new AddTask(list);
threads[i] = new Thread(task);
threads[i].start();
}
System.out.printf("Main %d AddTask have been launched\n", threads.length);
for(int i=0;i<threads.length;i++){
threads[i].join();
}
System.out.printf("Main size of threads %d\n", list.size());
for(int i=0;i<threads.length;i++){
RemoveTask removeTask = new RemoveTask(list);
threads[i] = new Thread(removeTask);
threads[i].start();
}
System.out.printf("Main %d RemoveTask have been launched\n", threads.length);
for(int i=0;i<threads.length;i++){
threads[i].join();
}
System.out.printf("Main size of threads %d\n", list.size());
}
}
CopyOnWriteArrayList
CopyOnWriteArraySet