java 线程包_Java 多线程——工具包
JUC
首先來說說synchronized的有什么缺點。
它非常的死板。要么獲取鎖,要么等待鎖,而且我們無法知曉此時這個鎖有沒有被人拿到,也不知道某個線程是否是上鎖狀態。
只有悲觀鎖、排他鎖,沒有樂觀鎖、共享鎖。有些資源允許很多線程去讀,但是只允許一個線程寫,這樣的鎖叫做共享鎖。悲觀鎖就是做某個操作必須要拿到一個鎖。樂觀鎖就是先去把一個任務做完,但由于多個線程競爭這個操作沒有正確完成,那就重新做一遍,直到正確為止。
性能相對較差
java.util.concurrent簡稱JUC,是Java的并發工具包,解決了上述的一些問題。
Lock / Condition
Lock提供了一個更加復雜的鎖機制。它允許更加靈活的結構,支持不同的方法,支持相關的Condition操作。
同一個鎖可以有多個條件。
讀寫分離。Lock的實現中有讀鎖WriteLock和寫鎖ReadLock。
tryLock方法。如果該鎖可用立刻返回true,不可用則立刻返回false。
可以方便的實現更加靈活的優先級/公平性。公平性指的是,假如有多個線程競爭一個鎖的話,我以什么順序給它們。非公平鎖,主要靠操作系統的調度。Lock的實現中有可重入鎖ReentrantLock(默認是非公平鎖,可以傳一個參數讓它變成公平鎖)。
Conditon把Object的monitor方法(wait,notify,notifyAll)拆出來成了獨立的對象,使得支持多個等待集合。
CountDownLatch
倒數閉鎖。
用于協調一組線程的工作。
它的API簡單暴力countDown(),await()。以下是一個使用例子:
public class Main {
public static void main(String[] args) throws InterruptedException {
final CountDownLatch countDownLatch = new CountDownLatch(10);
for (int i = 0; i < 10; i++) {
int finalI = i;
new Thread(() -> {
int second = new Random().nextInt(10);
try {
Thread.sleep(second * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程" + finalI + "干完活了");
countDownLatch.countDown();
}).start();
}
countDownLatch.await();
System.out.println("老板發話了,所有人干完活了!");
}
}
CyclicBarrier
循環的屏障
等所有線程執行完了,才繼續:
public class Main {
public static void main(String[] args) throws InterruptedException {
final CyclicBarrier cyclicBarrier = new CyclicBarrier(5);
for (int i = 0; i < 5; i++) {
int finalI = i;
new Thread(() -> {
int second = new Random().nextInt(10);
try {
Thread.sleep(second * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("線程" + finalI + "干完活了");
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("所有線程都執行完了,大家一起說!");
}).start();
}
}
}
Semaphore
信號量
信號量的獲取和釋放
BlockingQueue & BlockingDeque
傳統的集合框架的操作要么正常返回,要么丟出異常,BlockingQueue/BlockingDeque提供?種「等待」的可能。
API: 阻塞操作:put/take。
先聲明容量大小,如果put超過容量,則會等待另一個線程take。
BlockingQueue先進先出。BlockingDeque頭尾都能進出,更加靈活。
Future & ExecutorService
Future代表?個「未來才會發?的事情」。
Future本身是?即返回的。
get()會阻塞并返回執?結果,并拋出可能的異常。異常的拋出一般只會在當前線程,而get可以把其他線程的異常轉移到當前線程拋出。
線程池的參數。建議看ExecutorService的一個實現:ThreadPoolExecutor文檔。
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters and default rejected execution handler.
*
-----* 核心線程的數量,哪怕它們閑下來,也不會被丟棄。
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
-----* 最多可以開這么多的線程工作。
* @param maximumPoolSize the maximum number of threads to allow in the
* poo
-----* 下面兩個是聯合使用的,非核心線程空閑多久會被殺死。
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
-----* 保存那些還沒被執行的任務。
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
-----* 每當你需要一個新的線程的時候,用它來創建。
* @param threadFactory the factory to use when the executor
* creates a new thread
-----* 假如任務來的太快,把任務隊列撐滿了,要采取何種策略?
-----* AbortPolicy丟棄策略、CallerRunsPolicy讓調用者執行
-----* DiscardOldestPolicy丟棄最老的一個任務、DiscardOldestPolicy丟棄最新的一個任務。
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
還可以舉一個通俗易懂的例子,假如你是一個老板,有如下的參數解釋:
corePoolSize 核?員?數量
maximumPoolSize 最?招募的員?數量
keepAliveTime/unit 員?閑下來多久之后炒掉他們
workQueue 訂單隊列
threadFactory 造?的??
handler 訂單實在太多的處理策略
Java 默認實現的線程池,使用Executors.xxx創建一個線程池,且這些方法大多都返回一個ThreadPoolExecutor,如下所示:
public static ExecutorService newxxxThreadPool(xxx) {
return new ThreadPoolExecutor(六個參數);
}
總結
以上是生活随笔為你收集整理的java 线程包_Java 多线程——工具包的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java fx消息通知,Java的FX
- 下一篇: java中bitconverter_C#