日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java一些常用并发工具示例

發布時間:2024/4/13 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java一些常用并发工具示例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近把《java并發編程實戰》-Java Consurrency in Practice 重溫了一遍,把書中提到的一些常用工具記錄于此:

一、閉鎖(門栓)-?CountDownLatch

適用場景:多線程測試時,通常為了精確計時,要求所有線程都ready后,才開始執行,防止有線程先起跑,造成不公平,類似的,所有線程執行完,整個程序才算運行完成。

/*** 閉鎖測試(菩提樹下的楊過 http://yjmyzz.cnblogs.com/)** @throws InterruptedException*/@Testpublic void countdownLatch() throws InterruptedException {CountDownLatch startLatch = new CountDownLatch(1); //類似發令槍CountDownLatch endLatch = new CountDownLatch(10);//這里的數量,要與線程數相同for (int i = 0; i < 10; i++) {Thread t = new Thread(() -> {try {startLatch.await(); //先等著,直到發令槍響,防止有線程先runSystem.out.println(Thread.currentThread().getName() + " is running...");Thread.sleep(10);} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {endLatch.countDown(); //每個線程執行完成后,計數}});t.setName("線程-" + i);t.start();}long start = System.currentTimeMillis();startLatch.countDown();//發令槍響,所有線程『開跑』endLatch.await();//等所有線程都完成long end = System.currentTimeMillis();System.out.println("done! exec time => " + (end - start) + " ms");}  

執行結果:

線程-1 is running...
線程-5 is running...
線程-8 is running...
線程-4 is running...
線程-3 is running...
線程-0 is running...
線程-2 is running...
線程-9 is running...
線程-7 is running...
線程-6 is running...
done! exec time => 13 ms

注:大家可以把第14行注釋掉,再看看運行結果有什么不同。

?

二、信號量(Semaphore)

適用場景:用于資源數有限制的并發訪問場景。

public class BoundedHashSet<T> {private final Set<T> set;private final Semaphore semaphore;public BoundedHashSet(int bound) {this.set = Collections.synchronizedSet(new HashSet<T>());this.semaphore = new Semaphore(bound);}public boolean add(T t) throws InterruptedException {if (!semaphore.tryAcquire(5, TimeUnit.SECONDS)) {return false;};boolean added = false;try {added = set.add(t);return added;} finally {if (!added) {semaphore.release();}}}public boolean remove(Object o) {boolean removed = set.remove(o);if (removed) {semaphore.release();}return removed;}}@Testpublic void semaphoreTest() throws InterruptedException {BoundedHashSet<String> set = new BoundedHashSet<>(5);for (int i = 0; i < 6; i++) {if (set.add(i + "")) {System.out.println(i + " added !");} else {System.out.println(i + " not add to Set!");}}}

上面的示例將一個普通的Set變成了有界容器。執行結果如下:

0 added !
1 added !
2 added !
3 added !
4 added !
5 not add to Set!

?

三、柵欄CyclicBarrier?

這個跟閉鎖類似,可以通過代碼設置一個『屏障』點,其它線程到達該點后才能繼續,常用于約束其它線程都到達某一狀態后,才允許做后面的事情。

public class Worker extends Thread {private CyclicBarrier cyclicBarrier;public Worker(CyclicBarrier cyclicBarrier) {this.cyclicBarrier = cyclicBarrier;}private void step1() {System.out.println(this.getName() + " step 1 ...");}private void step2() {System.out.println(this.getName() + " step 2 ...");}public void run() {step1();try {cyclicBarrier.await();} catch (InterruptedException e) {e.printStackTrace();} catch (BrokenBarrierException e) {e.printStackTrace();}step2();}}@Testpublic void cyclicBarrierTest() throws InterruptedException, BrokenBarrierException {CyclicBarrier cyclicBarrier = new CyclicBarrier(11);for (int i = 0; i < 10; i++) {Worker w = new Worker(cyclicBarrier);w.start();}cyclicBarrier.await();}

這里我們假設有一個worder線程,里面有2步操作,要求所有線程完成step1后,才能繼續step2. 執行結果如下:

Thread-0 step 1 ...
Thread-1 step 1 ...
Thread-2 step 1 ...
Thread-3 step 1 ...
Thread-4 step 1 ...
Thread-5 step 1 ...
Thread-6 step 1 ...
Thread-7 step 1 ...
Thread-8 step 1 ...
Thread-9 step 1 ...
Thread-9 step 2 ...
Thread-0 step 2 ...
Thread-3 step 2 ...
Thread-4 step 2 ...
Thread-6 step 2 ...
Thread-2 step 2 ...
Thread-1 step 2 ...
Thread-8 step 2 ...
Thread-7 step 2 ...
Thread-5 step 2 ...

?

四、Exchanger

如果2個線程需要交換數據,Exchanger就能派上用場了,見下面的示例:

@Testpublic void exchangerTest() {Exchanger<String> exchanger = new Exchanger<>();Thread t1 = new Thread(() -> {String temp = "AAAAAA";System.out.println("thread 1 交換前:" + temp);try {temp = exchanger.exchange(temp);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("thread 1 交換后:" + temp);});Thread t2 = new Thread(() -> {String temp = "BBBBBB";System.out.println("thread 2 交換前:" + temp);try {temp = exchanger.exchange(temp);} catch (InterruptedException e) {e.printStackTrace();}System.out.println("thread 2 交換后:" + temp);});t1.start();t2.start();}

 執行結果:

thread 1 交換前:AAAAAA
thread 2 交換前:BBBBBB
thread 2 交換后:AAAAAA
thread 1 交換后:BBBBBB

?

五、FutureTask/Future

一些很耗時的操作,可以用Future轉化成異步,不阻塞后續的處理,直到真正需要返回結果時調用get拿到結果

@Testpublic void futureTaskTest() throws ExecutionException, InterruptedException, TimeoutException {Callable<String> callable = () -> {System.out.println("很耗時的操作處理中。。。");Thread.sleep(5000);return "done";};FutureTask<String> futureTask = new FutureTask<>(callable);System.out.println("就緒。。。");new Thread(futureTask).start();System.out.println("主線程其它處理。。。");System.out.println(futureTask.get());System.out.println("處理完成!");System.out.println("-----------------");System.out.println("executor 就緒。。。");ExecutorService executorService = Executors.newSingleThreadExecutor();Future<String> future = executorService.submit(callable);System.out.println(future.get(10, TimeUnit.SECONDS));}

 執行結果:

就緒。。。
主線程其它處理。。。
很耗時的操作處理中。。。
done
處理完成!
-----------------
executor 就緒。。。
很耗時的操作處理中。。。
done

?

六、阻塞隊列BlockingQueue

阻塞隊列可以在線程間實現生產者-消費者模式。比如下面的示例:線程producer模擬快速生產數據,而線程consumer模擬慢速消費數據,當達到隊列的上限時(即:生產者產生的數據,已經放不下了),隊列就堵塞住了。

@Testpublic void blockingQueueTest() throws InterruptedException {final BlockingQueue<String> blockingDeque = new ArrayBlockingQueue<>(5);Thread producer = new Thread() {public void run() {Random rnd = new Random();while (true) {try {int i = rnd.nextInt(10000);blockingDeque.put(i + "");System.out.println(this.getName() + " 產生了一個數字:" + i);Thread.sleep(rnd.nextInt(50));//模擬生產者快速生產} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}};producer.setName("producer 1");Thread consumer = new Thread() {public void run() {while (true) {Random rnd = new Random();try {String i = blockingDeque.take();System.out.println(this.getName() + " 消費了一個數字:" + i);Thread.sleep(rnd.nextInt(10000));//消費者模擬慢速消費} catch (InterruptedException e) {Thread.currentThread().interrupt();}}}};consumer.setName("consumer 1");producer.start();consumer.start();while (true) {Thread.sleep(100);}}

執行結果:

producer 1 產生了一個數字:6773
consumer 1 消費了一個數字:6773
producer 1 產生了一個數字:4456
producer 1 產生了一個數字:8572
producer 1 產生了一個數字:5764
producer 1 產生了一個數字:2874
producer 1 產生了一個數字:780 # 注意這里就已經堵住了,直到有消費者消費一條數據,才能繼續生產
consumer 1 消費了一個數字:4456
producer 1 產生了一個數字:4193

總結

以上是生活随笔為你收集整理的java一些常用并发工具示例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 美女在线网站 | 亚洲天堂导航 | 色婷婷久久久 | 日韩亚洲欧美一区二区三区 | 91超碰在线免费观看 | 黄色aaa毛片 | 一区二区天堂 | 亚洲最新网址 | 五月天综合社区 | 亚洲第一天堂在线观看 | 久久中文字幕无码 | 久久一卡二卡 | 新婚之夜玷污岳丰满少妇在线观看 | 美女av网址| av大片在线观看 | 一区二区三区不卡在线观看 | 一级片免费网址 | 西西4444www大胆无码 | 天堂网2014av| 99re免费视频精品全部 | 国产网站免费看 | 日韩精品一区二区三区在线播放 | 日本肉体xxxx裸体137大胆图 | 中文资源在线观看 | 日本一区二区三区四区在线观看 | 成人在线观看网站 | 一级视频毛片 | 日产精品久久久一区二区 | 国产chinese中国hdxxxx | 久久综合区 | 日韩av免费网址 | 黄色一级视频免费看 | 丰满岳妇乱一区二区三区 | 极品在线播放 | 亚洲九九夜夜 | 91视频在线免费观看 | 国产成人无码精品久久二区三 | 日本乱码视频 | 一级性生活大片 | 1000部国产精品成人观看 | 美女超碰 | 日韩狠狠操 | 亚洲六月丁香色婷婷综合久久 | 欧洲天堂网 | 97在线精品视频 | 又黄又免费的网站 | 香蕉黄视频 | 精品无码久久久久久久久果冻 | 亚洲天天看 | 日韩av一级 | 8050午夜二级 | 欧美精品久久久久久久久久 | 五月天婷婷在线观看 | 成人日韩精品 | 色伊人网| 91色在线观看 | 中国免费一级片 | 麻豆视频一区 | 中国成人av| 九九九久久久 | 亚洲一级av无码毛片精品 | 啪啪在线视频 | 秘密基地动漫在线观看免费 | 国产微拍一区 | 欧美日韩激情在线一区二区三区 | 久久久久久夜 | 天天躁日日躁狠狠躁 | 天天干天天爽 | 97视频网站 | 少女国产免费观看 | 在线射| 激情亚洲| 茄子视频A| 一区二区三区在线视频免费观看 | 亚洲av中文无码乱人伦在线视色 | 射射av| 黄片毛片在线免费观看 | 在线观看一区二区三区视频 | 美女被男人桶出白浆喷水 | 国产精品电影网站 | 97人人射 | 国产网址在线 | 亚洲国产精品成人综合久久久 | 国产小视频免费在线观看 | 中文字幕第十二页 | 天堂福利在线 | 国产精品自慰网站 | 精品国产伦一区二区三区免费 | 一级做a免费 | 日本久久激情 | 亚洲乱码国产乱码精品精的特点 | 黄页网站免费在线观看 | 久久精品7| 精品国产一区二区三区久久 | 国产精品推荐 | 丰满少妇乱子伦精品看片 | 久久午夜免费视频 | 伊人影院在线观看视频 | 操久久久|