大家好,我是哪吒。
上一篇簡單聊一聊公平鎖和非公平鎖,parallel并行流,提到了一個IntStream.rangeClosed并行流問題,很多小伙伴,對這個比較陌生,想用線程池的方式改造一下。
@Datapublic class LockTest1 { public static void main(String[] args) { IntStream.rangeClosed(1, 100000).parallel().forEach(i -> new LockTest1().increase()); System.out.println(time); } private static int time = 0; private static Object lock = new Object(); public void increase() { synchronized (lock) { time++; } }}
不會那些新特性,還是原始的香啊,寫起代碼,得心應手。
這時候,有些小伙伴,又陷入了選擇恐懼癥。用哪個線程池比較好呢?
簡單回顧一下:
最常用的還是固定線程數線程池newFixedThreadPool(10)。
@Datapublic class LockTest2 { public static void main(String[] args) { ExecutorService executorService = Executors.newFixedThreadPool(200); for (int i = 0; i < 100000; i++) { Thread0926 thread = new Thread0926(); executorService.execute(thread); } System.out.println(time); } private static int time = 0; private static Object lock = new Object(); public void increase() { synchronized (lock) { time++; } }}
public class Thread0926 implements Runnable{ @Override public void run() { LockTest2 lockTest = new LockTest2(); lockTest.increase(); }}
我草,這不對啊,不應該是100000嘛?又把老子整不會了~
上一篇測試過,使用synchronized代碼塊是可以解決i++線程安全問題的,這次怎么不好使了?
上面的代碼中,synchronized (lock)鎖住了time++,lock是靜態變量,所以屬于類級別的鎖。但是新建的線程是一個新的類,超出了鎖的范圍,所以失效。
那么,在當前類中,開啟線程,是不是就可以了呢?試一下
public class LockTest4 { private static int time = 0; private static Object lock = new Object(); public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 200; i++) { Thread thread = new Thread(() -> { for (int j = 0; j < 500; j++) { synchronized (lock) { time++; } } }); thread.start(); } Thread.sleep(3000); System.out.println(time); }}
當然,在synchronized代碼塊中,使用synchronized (LockTest4.class)也是可以的,效果是一樣的。
并行流的本質的是并行,多線程的本質是并發。
并行指當多核CPU中的一個CPU執行一個線程時,其它CPU能夠同時執行另一個線程,兩個線程之間不會搶占CPU資源,可以同時運行。
并發指在一段時間內CPU處理多個線程,這些線程會搶占CPU資源,CPU資源根據時間片周期在多個線程之間來回切換,多個線程在一段時間內同時運行,而在同一時刻不是同時運行的。
場景應用程序開發,提供http接口、數據庫查詢、微服務調用都是IO請求,IO請求時幾乎不消耗cpu,這是為了提供cup使用率,建議使用多線程并發,線程數可以遠大于cpu核數。
對應大量的加減乘除運算、md5、hash等運算操作,需要持續使用cpu,需要讓多核cpu并行運算,適合使用forkjoin并行計算。
技術場景多線程不足,使用多線程技術,也能提高性能,但是線程設置過大會浪費cpu線程切換的時間,如果線程任務分配不均勻,會導致有的cpu忙碌有的cpu空閑。
本文鏈接:http://www.www897cc.com/showinfo-26-13523-0.html通過線程池方式改造Stream.parallel()并行流
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: C# Dev Kit for Visual Studio Code 用法詳解
下一篇: Java中equals和==的區別