Concurrent集合 Atomic类
生活随笔
收集整理的這篇文章主要介紹了
Concurrent集合 Atomic类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Block Queue的意思就是說當一個線程調用getTask方法的時候會讓線程進入等待狀態直到條件滿足,線程被喚醒以后,getTask方法才會被返回
java.util.concurrent包里面就提供了線程安全的BlockQueue集合ArrayBlockQueue就已經實現了線程安全的Block Queue
package com.leon.day05;import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class TaskQueueDemo {public static void main(String[] args) throws InterruptedException {// 最后我們通過一個main方法創建一個TaskQueue// 我們不需要自己編寫一個BlockingQueue,我們可以直接使用ArrayBlockingQueueBlockingQueue<String> taskQueue = new ArrayBlockingQueue<>(100);// 然后我們添加三個任務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");}}class WorkerThread extends Thread{// 當我們直接使用BlockQueue的時候,我們的代碼又被大大的簡化了BlockingQueue<String> taskQueue;public WorkerThread(BlockingQueue<String> taskQueue) {this.taskQueue = taskQueue;}@Overridepublic void run() {while(!isInterrupted()) {String name;try {// take方法就是BlockingQueue提供的一個blocking方法// 當我們調用這個方法的時候線程會阻塞,直到條件滿足,線程才會返回name = taskQueue.take();} catch (InterruptedException e) {break;}String result = "Hello, " + name + "!";System.out.println(result);} }}直接結果和我們自己編寫原始的Block加Condition實現的邏輯一模一樣的,但是我們編寫的代碼被大大的簡化了
對于List來說,ArrayList是非線程安全的,線程安全的是CopyOnWriteArrayListHashMap的安全版本是ConcurrentHashMapHashSet和TreeSet對應的是CopyOnWriteArrayList我們可以根據需要根據JDK提供的安全版本
Collections是一個工具類,例如把一個HashMap轉為一個線程安全的HashMap,我們會通過Collections.synchronizedMap(unsafeHashMap),得到一個線程安全的map.但實際上他是使用了一個包裝類,包裝了一個非線程安全的Map,然后會對所有的synchronized方法加鎖,這樣獲得線程安全比Coccurent獲得的集合效率低很多,所以我們現在已經不推薦使用了.
使用java.util.cocurrent提供的Block集合可以簡化多線程編程.1. 多線程同時訪問Blocking集合是安全的2. 盡量使用JDK提供的coccurent集合,避免自己編寫同步代碼
java.util.cocurrent.atomic提供了一組原子類型的操作:例如 AtomicIntegerint addAndGet(int delta)int incrementAndGet();int get();int compareAndSet(int expect, int update);
Atomic類可以實現:1. 無鎖(lock-free)實現的線程安全(thread-safe)的訪問
Compare and Set 是指在這個操作中,如果Atomic當前的值是prev,就更新為next. 然后返回true如果prev當前的值不等于next,就什么也不干,返回false.利用CAS操作,可以保證即使在 do...while操作中其他線程修改了Atomic的值,最終的結果也一定是正確的.
我們通過一個AtomicLong調用incrementAndGet()方法就可以非常容易的實現一個多線程安全的計時器
package com.leon.day05;import java.util.concurrent.atomic.AtomicInteger;class Counter {private AtomicInteger value = new AtomicInteger(0);// add方法是一個修改方法,所以用wLock,解鎖加鎖public int add(int m) {return this.value.addAndGet(m);}// 對于dec方法也是寫鎖public int dec(int m) {return this.value.addAndGet(-m);}// 但是對于get方法只需要使用一個讀鎖,這樣多個線程就可以獲取讀鎖public int get() {return this.value.get();}}public class Main {final static int LOOP = 100;// 在main方法中啟動兩個線程,分別調用add和dec方法,public static void main(String[] args) throws InterruptedException {Counter counter = new Counter();Thread t1 = new Thread() {@Overridepublic void run() {for(int i=0;i<LOOP;i++) {counter.add(1);}}};Thread t2 = new Thread() {@Overridepublic void run() {for(int i=0;i<LOOP;i++) {counter.dec(1);}}};t1.start();t2.start();t1.join();t2.join();System.out.println(counter.get());}}得到的結果和synchronized和ReentrantLock是一樣的
使用java.util.atomic提供的原子操作可以簡化多線程編程.AtomicInteger/AtomicLong/AtomicIntegerArray等原子操作實現了無鎖的線程安全適用于計數器,累加器等
?
總結
以上是生活随笔為你收集整理的Concurrent集合 Atomic类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Condition - Java多线程编
- 下一篇: jvm结构