Java笔记-concurrent集合及线程池
reentrantLock + condition實現 Blocking queue。
java.util.concurrent提供了線程安全的Blocking集合:ArrayBlockingQueue
程序運行截圖如下:
源碼如下:
import java.lang.reflect.Array; 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;}@Overridepublic void run() {while(!isInterrupted()){String name = "";try{name = taskQueue.take();}catch (InterruptedException e){break;}String result = "Hello " + name + " !";System.out.println(result);}} }public class Main1 {public static void main(String[] args) throws InterruptedException {BlockingQueue<String> taskQueue = new ArrayBlockingQueue<String>(1000);WorkerThread workerThread = new WorkerThread(taskQueue);workerThread.start();taskQueue.put("小紅");Thread.sleep(1000);taskQueue.put("小剛");Thread.sleep(1000);taskQueue.put("小明");Thread.sleep(1000);workerThread.interrupt();workerThread.join();System.out.println("END");} }| Interface | Non-thread safe | Thread safe |
| List | ArrayList | CopyOnWriteArrayList |
| Map | HashMap | ConcurrentHashMap |
| Set | HashSet, TreeSet | CopyOnWriteArraySet |
| Queue | ArrayDeque, LinkedList | ArrayBlockingQueue, LinkedBlockingQueue |
| Deque | ArrayDequeue, LinkedList | LinkedBlockingDeque |
java.util.Collections工具類還提供了舊的線程安全集合轉換器:
Map unsafeMap = new HashMap(); Map threadSafeMap = Collections.synchronizedMap(unsafeMap);使用java.util.concurrent提供的Blocking集合可以簡化多線程編程:
多線程同時訪問Blocking集合是安全的。
盡可能使用JDK提供的concurrent集合,避免自己編寫同步代碼。
?
Atomic
java.util.concurrent.atomic提供了一組原子類型操作。
Atomic類可以實現:
無鎖(lock-free)實現的線程安全(thread-safe)訪問
程序運行截圖如下:
代碼如下:
import java.util.concurrent.atomic.AtomicInteger;class Counter{private AtomicInteger value = new AtomicInteger(0);public int add(int m){//System.out.println("add: " + value.get());return this.value.addAndGet(m);}public int dec(int m){//System.out.println("dec: " + value.get());return this.value.addAndGet(-m);}public int get(){return this.value.get();} } public class Main2 {static final private int LOOP = 1000;public static void main(String[] args) throws InterruptedException {final 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:" + counter.get());} }使用java.util.atomic提供的原子操作可以簡化多線程編程:
AtomicInteger/AtomicLong/AtomicIntegerArray。
原子操作實現了無鎖的線程安全。
適用于計數器,累加器。
?
ExecutorService
Java語言內置多線程支持:
創建線程需要操作系統資源(線程資源,棧空間...)
頻繁串講和消耗線程需要大量事件。
?
線程池:
線程池維護若干個線程,處于等待狀態。
如果有新任務,就分配一個空閑線程執行。
如果所有線程都處于忙碌狀態,新任務放入隊列等待
?
程序運行截圖如下:
源碼如下:
import java.util.concurrent.*;class PrintTask implements Runnable{String name;public PrintTask(String name){this.name = name;}public void run() {for(int i = 0; i < 3; i++){System.out.println("Hello " + name + " !");try{Thread.sleep(1000);}catch (InterruptedException e){}}} }public class Main3 {public static void main(String[] args) throws InterruptedException {//ExecutorService executor = Executors.newFixedThreadPool(3);//ExecutorService executor = Executors.newSingleThreadExecutor();//ExecutorService executor = Executors.newCachedThreadPool();ExecutorService executor = new ThreadPoolExecutor(0, 10, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());executor.submit(new PrintTask("小明"));executor.submit(new PrintTask("小紅"));executor.submit(new PrintTask("小剛"));executor.submit(new PrintTask("小粉"));Thread.sleep(10000);executor.shutdown();} }?
常用ExecutorService:
FixedThreadPool:線程數固定
CachedThreadPool:線程數根據任務動態調整
SingleThreadExecutor:僅單線程執行
?
多線程?
ScheduledThreadPool:一個任務可以定期反復執行
程序運行截圖如下;
源碼如下:
import java.text.SimpleDateFormat; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit;class HelloTask implements Runnable{String name;public HelloTask(String name){this.name = name;}public void run() {System.out.println("Hello " + name + " !");try{Thread.sleep(1000);}catch (InterruptedException e){}SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println("GOODBYE " + name + " " + df.format(System.currentTimeMillis()));} }public class Main4 {public static void main(String[] args){ScheduledExecutorService executor = Executors.newScheduledThreadPool(3);executor.scheduleAtFixedRate(new HelloTask("小明"), 2, 5, TimeUnit.SECONDS);executor.scheduleAtFixedRate(new HelloTask("小紅"), 2, 5, TimeUnit.SECONDS);} }?
總結
以上是生活随笔為你收集整理的Java笔记-concurrent集合及线程池的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++工作笔记-使用namespace构
- 下一篇: C++笔记-using的进一步用法