java多線程-java併發數據結構

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;
/**
 * @ClassName:list
 * @Description:
 * @author: Torey
 */
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());
        //輸出list中的值
        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;
/**
 * @ClassName:SetTest
 * @Description:
 * @author: Torey
 */
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());
        //輸出set的值
        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;

/**
 * @ClassName:MapTest
 * @Description:
 * @author: Torey
 */
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());
        //輸出set的值
        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;

/**
 * @ClassName:QueueTest
 * @Description:
 * @author: Torey
 */
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();
        }
        //等待2秒
        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());
        //輸出queue中的值
        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中
            queue.add(Thread.currentThread().getName());

        }
    }
}

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章