JavaEE進階知識學習----多執行緒JUC高階知識-5-執行緒池-Callable-執行緒排程
11.執行緒池
先看一個簡單的例項
public class TestThreadPool {
public static void main(String[] args) {
ThreadPoolDemo td = new ThreadPoolDemo();
new Thread(td).start();
new Thread(td).start();
new Thread(td).start();
}
}
class ThreadPoolDemo implements Runnable{
private int i = 0;
@Override
public void run() {
while (i<= 100) {
System.out.println(Thread.currentThread().getName());
}
}
}
上面我們就是建立和銷燬了三個執行緒例項,這樣不斷的建立和銷燬,就會消耗資源,於是就出現了執行緒池,和資料庫連線池一樣,就是有許多的執行緒已經建立好了,我們直接使用就好。
執行緒池:提供了一個執行緒佇列,佇列中儲存著所有等待狀態的執行緒,避免了建立與銷燬額外的開銷,提高了響應的效能。
執行緒池的體系結構
java.util.concurrent.Executor:負責執行緒的使用與排程的根介面
一個 ExecutorService,它使用可能的幾個池執行緒之一執行每個提交的任務,通常使用 Executors 工廠方法配置。
執行緒池可以解決兩個不同問題:由於減少了每個任務呼叫的開銷,它們通常可以在執行大量非同步任務時提供增強的效能,並且還可以提供繫結和管理資源(包括執行任務集時使用的執行緒)的方法。每個 ThreadPoolExecutor 還維護著一些基本的統計資料,如完成的任務數。
工具類Executor
- ExecutorService newFixedThreadPool(int nThreads) 建立一個可重用固定執行緒數的執行緒池,以共享的無界佇列方式來執行這些執行緒。
- ExecutorService newCachedThreadPool() 建立一個可根據需要建立新執行緒的執行緒池
- static ExecutorService newSingleThreadExecutor() 建立一個使用單個 worker 執行緒的 Executor
- static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) 建立一個執行緒池,它可安排在給定延遲後執行命令或者定期地執行。
執行緒池的使用方法如下:
public class TestThreadPool {
public static void main(String[] args) {
// 1.建立執行緒池
ExecutorService pool = Executors.newFixedThreadPool(5);//建立了5個執行緒的執行緒池
ThreadPoolDemo td = new ThreadPoolDemo();
// 2.為執行緒池中的執行緒分配任務
for (int i = 0; i < 10; i++) {
pool.submit(td);
}
// 3.關閉執行緒池
pool.shutdown();
}
}
class ThreadPoolDemo implements Runnable{
private int i = 0;
@Override
public void run() {
while (i<= 5) {
System.out.println(Thread.currentThread().getName()+":"+i++);
}
}
}
使用Callable建立執行緒的方式
public class TestThreadPool {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 1.建立執行緒池
ExecutorService pool = Executors.newFixedThreadPool(5);//建立了5個執行緒的執行緒池
List<Future<Integer>> list = new ArrayList<Future<Integer>>();
for (int i = 0; i < 10; i++) {
Future<Integer> future = pool.submit(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i < 100; i++) {
sum +=i;
}
return sum;
}
});
list.add(future);
}
// 3.關閉執行緒池
pool.shutdown();
for (Future<Integer> future: list) {
System.out.println(future.get());
}
}
}
12.執行緒排程
線上程池中提到了一個ScheduledExecutorService這一個類就是用來實現執行緒的排程的。
public class TestScheduledThread {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ScheduledExecutorService pool = Executors.newScheduledThreadPool(5);// 建立五個執行緒的執行緒池
for (int i = 0; i < 5; i++) {
ScheduledFuture<Integer> result = pool.schedule(new Callable<Integer>() {
@Override
public Integer call() throws Exception {
int num = new Random().nextInt(100);//產生隨機數
System.out.println(Thread.currentThread().getName()+":"+num);
return num;
}
}, 3, TimeUnit.SECONDS);
System.out.println(result.get());
}
pool.shutdown();
}
}
13.Fork/Join框架
Fork/Join框架就是在必要的情況下,將一個大任務,進行拆分(fork)成若干個小任務(拆到不可再拆為止,即臨界值),再將一個個的小任務運算的結果進行join彙總,這裡要說明的是拆分和合並也需要時間,例如求100的累加和,可以使用for迴圈直接累加,也可以使用Fork/Join,但是執行時間反而是for迴圈要快的多,如果要計算100000000就是Fork/Join要快的多,所以包括臨界值的設定都要不停的測試得出,下面給出一個例項吧。
public class TestForkJoinPool {
public static void main(String[] args) {
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinSum(0L, 1000000L);
long sum = pool.invoke(task);
System.out.println(sum);
}
}
class ForkJoinSum extends RecursiveTask<Long>{
private static final long serialVersionUID = 1L;
private long start;
private long end;
private static final long THURSHOLD = 10000L;// 臨界值
public ForkJoinSum(long start,long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long length = end -start;
if(length <= THURSHOLD){
long sum = 0L;
for(long i = start; i<= end;i++){
sum +=i;
}
return sum;
}else{
long middle = (end+start) / 2;
ForkJoinSum left = new ForkJoinSum(start, middle);//遞迴操作
left.fork();// 進行拆分,同時壓入執行緒佇列
ForkJoinSum right = new ForkJoinSum(middle+1, end);
right.fork();
return left.join()+right.join();
}
}
}
相關文章
- 多執行緒(三)、執行緒池 ThreadPoolExecutor 知識點總結執行緒thread
- 多執行緒基礎必要知識點!看了學習多執行緒事半功倍執行緒
- JUC執行緒高階---執行緒控制通訊Condition執行緒
- 多執行緒------執行緒與程式/執行緒排程/建立執行緒執行緒
- 《Java 高階篇》七:執行緒和執行緒池Java執行緒
- 執行緒學習知識總結執行緒
- 多執行緒之初識執行緒執行緒
- 多執行緒基礎知識執行緒
- Java執行緒池進階Java執行緒
- 執行緒池知識點詳解執行緒
- Java多執行緒學習(五)執行緒間通訊知識點補充Java執行緒
- 多執行緒【執行緒池】執行緒
- 《面試補習》- 多執行緒知識梳理面試執行緒
- 【初識】-JUC·ThreadPoolExecutor 執行緒池thread執行緒
- 【重學Java】多執行緒進階(執行緒池、原子性、併發工具類)Java執行緒
- 進階Java多執行緒Java執行緒
- Java多執行緒相關知識Java執行緒
- 執行緒基本知識點執行緒
- 多執行緒知識梳理(5) 執行緒池四部曲之 Executor 框架執行緒框架
- 多執行緒知識梳理(6) 執行緒池四部曲之 ThreadPoolExecutor執行緒thread
- Java多執行緒——執行緒池Java執行緒
- 多執行緒系列(一):認識執行緒執行緒
- C#多執行緒學習(四) 多執行緒的自動管理(執行緒池)C#執行緒
- C# 多執行緒學習(4) :多執行緒的自動管理(執行緒池)C#執行緒
- java多執行緒9:執行緒池Java執行緒
- kuangshenshuo-多執行緒-執行緒池執行緒
- JavaThread多執行緒執行緒池Javathread執行緒
- Java多執行緒18:執行緒池Java執行緒
- 多執行緒之手撕執行緒池執行緒
- 多執行緒基礎知識點梳理執行緒
- Java進階05 多執行緒Java執行緒
- [shell進階]——shell多執行緒執行緒
- 三、執行緒池知識點整理筆記執行緒筆記
- 前置知識—程式和執行緒執行緒
- Java多執行緒學習(八)執行緒池與Executor 框架Java執行緒框架
- 執行緒池建立執行緒的過程執行緒
- 6.JUC執行緒高階-Lock同步鎖執行緒
- Android多執行緒之執行緒池Android執行緒