廖雪峯Java11多線程編程-3高級concurrent包-4Concurrent集合

1. Concurrent

用ReentrantLock+Condition實現Blocking Queue。java

class TaskQueue{
    final Queue<String> queue = new LinkedList<>();
    final Lock lock = new ReentrantLock();
    final Condition noEmpty = lock.newCondition();
    public String getTask(){...}
    public void addTask(String name){...}
}

Blocking Queue:當一個線程調用這個Queue的getTask()時,該方法內部可能讓給線程變成等待狀態,直到條件知足。線程被喚醒之後,getTask()纔會返回。 而java.util.concurrent提供了線程安全的Blocking集合,如ArrayBlockingQueue就已經包含了一個線程安全的BlockingQueue。編程

2. 示例

當咱們使用BlockingQueue的時候,咱們的代碼又被大大的簡化了。take()是BlockingQueue提供的一個Blocking方法。當咱們調用take()方法的時候,在內部可能會被阻塞,直到條件知足線程纔會返回。安全

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

class WorkerThread extends Thread{
    BlockingQueue<String> taskQueue;
    public WorkerThread(BlockingQueue<String> taskQueue){
        this.taskQueue = taskQueue;
    }
    public void run(){
        while(!isInterrupted()){
            String name;
            try{
                name = taskQueue.take();
            }catch (InterruptedException e){
                break;
            }
            String result = "Hello,"+name+"!";
            System.out.println(result);
        }
    }
}
public class Main{
    public static  void main(String[] args) throws Exception{
    //在main方法中,咱們不須要本身編寫一個BlockingQueue。咱們能夠直接使用ArrayBlockingQueue,而後向Queue中添加3個任務
        BlockingQueue<String> taskQueue = new ArrayBlockingQueue<>(1000);
        WorkerThread worker = new WorkerThread(taskQueue);
        worker.start();
        taskQueue.put("Bob");
        Thread.sleep(1000);
        taskQueue.put("Alice");
        Thread.sleep(1000);
        taskQueue.put("Tim");
        Thread.sleep(1000);
        worker.interrupt();
        worker.join();
        System.out.println("END");
    }
}

<img src="https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190613123711859-1656906421.png" width="500" /> ## 3.java.util.concurrent提供了線程安全的Blocking集合 <img src="https://img2018.cnblogs.com/blog/1418970/201906/1418970-20190613125222851-1359401381.png" width="600" /> ## 4.java.util.Collections工具類 java.util.Collections工具類還提供了舊的線程安全集合轉換器: 如把一個HashMap轉化爲一個線程安全的Map。實際上使用一個線程類,包裝了非線程安全的map,而後對全部的讀寫方法都用synchronized加鎖,這樣得到了線程安全的集合。它的性能比Concurrent低不少,不推薦使用。。 ```#java Map unsafeMap = new HashMap(); Map threadSafeMap = Collections.synchronizedMap(unsafeMap); ```多線程

5. 總結:

使用java.util.concurrent提供的Blocking集合能夠簡化多線程編程工具

  • 多線程同時訪問Blocking集合是安全的
  • 儘可能使用JDK提供的concurrent集合,避免本身編寫同步代碼
相關文章
相關標籤/搜索