java并发数据结构
- 常用的数据结构是线程不安全的
– ArrayList,HashMap, HashSet非同步的,这些在多线程中是不适用的
– 多个线程同时读写,可能会抛出异常或数据错误 - 传统Vector,Hashtable等同步集合性能过差
- 并发数据结构:数据添加和删除
– 阻塞式集合:当集合为空或者满时,等待
– 非阻塞式集合:当集合为空或者满时,不等待,返回null或异常 - List
– Vector 同步安全,写多读少
– ArrayList 不安全
– Collections.synchronaizedList(List list) 基于synchronized,效率差,线程安全
– CopyOnWriteArrayList 适合读多写少,基于复制机制,非阻塞,性能比较好(JDK 5) - Set
– HashSet 不安全
– Collectionss.synchronizedSet(Set set) 基于synchronized,效率差,线程安全
– CopyOnWriteArraySet(基于CopyOnWriteArrayList实现) 读多写少,非阻塞,线程安全 - Map
– Hashtable 同步安全,写多读少,性能不是很好
– HashMap 不安全
– Collections.synchronizedMap(Map map) 基于synchronized, 效率差
– ConcurrentHashMap 读多写少,非阻塞 - Queue & Deque(队列,JDK1.5提出)
– ConcurrentLinkedQueue 非阻塞
– ArrayBlockingQueue/LinkedBlockingQueue 阻塞
synchronized所包围的代码,一次只能由一个线程来执行。
Deque 是双向队列,两头都可以插入元素
list代码示例:
package com.torey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
public class ListTest {
public static void main(String[] args) {
List<String> unsafeList=new ArrayList<>();
List<String> safeList= Collections.synchronizedList(new ArrayList<String>());
CopyOnWriteArrayList<String> copySafeList=new CopyOnWriteArrayList<>();
ListThread t1 = new ListThread(unsafeList);
ListThread t2 = new ListThread(safeList);
ListThread t3 = new ListThread(copySafeList);
for (int i = 0; i < 10; i++) {
new Thread(t1,String.valueOf(i)).start();
new Thread(t2,String.valueOf(i)).start();
new Thread(t3,String.valueOf(i)).start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("t1:"+t1.list.size());
System.out.println("t2:"+t2.list.size());
System.out.println("t3:"+t3.list.size());
System.out.println("unsafeList:");
for (String s : t1.list) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("safeList:");
for (String s : t2.list) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("copySafeList:");
for (String s : t3.list) {
System.out.print(s + " ");
}
}
}
class ListThread implements Runnable{
public List<String> list;
public ListThread(List<String> list) {
this.list = list;
}
@Override
public void run() {
int i=0;
while (i<10){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add(Thread.currentThread().getName());
i++;
}
}
}
set代码示例:
package com.torey;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
public class SetTest {
public static void main(String[] args){
Set<String> unsafeSet=new HashSet<>();
Set<String> safeSet= Collections.synchronizedSet(new HashSet<>());
CopyOnWriteArraySet<String> safeSet2 = new CopyOnWriteArraySet<>();
SetThread set1 = new SetThread(unsafeSet);
SetThread set2 = new SetThread(safeSet);
SetThread set3 = new SetThread(safeSet2);
for (int i = 0; i < 10; i++) {
new Thread(set1,String.valueOf(i)).start();
new Thread(set2,String.valueOf(i)).start();
new Thread(set3,String.valueOf(i)).start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("set1="+set1.setTest.size());
System.out.println("set2="+set2.setTest.size());
System.out.println("set3="+set3.setTest.size());
System.out.println("unsafeList:");
for (String s : set1.setTest) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("safeList:");
for (String s : set2.setTest) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("copySafeList:");
for (String s : set3.setTest) {
System.out.print(s + " ");
}
}
}
class SetThread implements Runnable{
public Set<String> setTest;
public SetThread(Set<String> setTest) {
this.setTest = setTest;
}
@Override
public void run() {
int i=0;
while (i<10){
i++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
setTest.add(Thread.currentThread().getName()+i);
}
}
}
map示例:
package com.torey;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MapTest {
public static void main(String[] args){
Map<String,Integer> mapTest=new HashMap<>();
Map<String, Integer> synchronizedMap = Collections.synchronizedMap(new HashMap<String, Integer>());
ConcurrentHashMap<String,Integer> concurrentHashMap=new ConcurrentHashMap<>();
MapThread mapThread = new MapThread(mapTest);
MapThread synchronizedMapThread= new MapThread(synchronizedMap);
MapThread concurrentHashMapThread = new MapThread(concurrentHashMap);
for (int i = 0; i < 10; i++) {
new Thread(mapThread).start();
new Thread(synchronizedMapThread).start();
new Thread(concurrentHashMapThread).start();
}
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(mapThread.mapList.size());
System.out.println(synchronizedMapThread.mapList.size());
System.out.println(concurrentHashMapThread.mapList.size());
System.out.println("mapThread:");
for (String s : mapThread.mapList.keySet()) {
System.out.print(mapThread.mapList.get(s) + " ");
}
System.out.println();
System.out.println("synchronizedMapThread:");
for (String s : synchronizedMapThread.mapList.keySet()) {
System.out.print(synchronizedMapThread.mapList.get(s) + " ");
}
System.out.println();
System.out.println("concurrentHashMapThread:");
for (String s : concurrentHashMapThread.mapList.keySet()) {
System.out.print(concurrentHashMapThread.mapList.get(s) + " ");
}
}
}
class MapThread implements Runnable{
public Map<String,Integer> mapList;
public MapThread(Map<String, Integer> mapList) {
this.mapList = mapList;
}
@Override
public void run() {
int i=0;
while (i<10){
i++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
mapList.put(Thread.currentThread().getName()+i,i);
}
}
}
Queue多线程测试
package com.torey;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentLinkedDeque;
public class QueueTest {
public static void main(String[] args) throws InterruptedException {
Deque<String> unsafeQueue=new ArrayDeque<>();
ConcurrentLinkedDeque<String> safeQueue1=new ConcurrentLinkedDeque<String>();
ArrayBlockingQueue<String> safeQueue2=new ArrayBlockingQueue<>(100);
QueueThread t1 = new QueueThread(unsafeQueue);
QueueThread t2 = new QueueThread(safeQueue1);
QueueThread t3 = new QueueThread(safeQueue2);
for (int i = 0; i < 10; i++) {
new Thread(t1,String.valueOf(i)).start();
new Thread(t2,String.valueOf(i)).start();
new Thread(t3,String.valueOf(i)).start();
}
Thread.sleep(2000);
System.out.println("t1.queue.size()" + t1.queue.size());
System.out.println("t2.queue.size()" + t2.queue.size());
System.out.println("t3.queue.size()" + t3.queue.size());
System.out.println("t1:");
for (String s : t1.queue) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("t2:");
for (String s : t2.queue) {
System.out.print(s + " ");
}
System.out.println();
System.out.println("t3:");
for (String s : t3.queue) {
System.out.print(s + " ");
}
}
}
class QueueThread implements Runnable{
public Queue<String> queue;
public QueueThread(Queue<String> queue) {
this.queue = queue;
}
@Override
public void run() {
int i=0;
while (i<10){
i++;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
queue.add(Thread.currentThread().getName());
}
}
}
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e02ce0ed0f50343b5278a44d18f60e83.png)