91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

jdk線程池怎么實現

發布時間:2023-04-04 16:43:48 來源:億速云 閱讀:264 作者:iii 欄目:開發技術

本篇內容介紹了“jdk線程池怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

jdk線程池ThreadPoolExecutor的7個參數

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

corePoolSize

核心線程個數 ,int類型

maximunPoolSize

最大線程數 ,int類型

keepAliveTime存活時間

傳long類型的值,

當線程池中的線程數大于corePoolSize核心線程個數,且線程是閑置狀態,則這些空閑線程的最大存活時間是KeepAliveTime

TimeUnit

存活時間的單位, 有時/分/秒/毫秒等可選配置

workQueue

存放待執行任務的阻塞隊列, 可傳入

arrayBlockingQueue 基于數組的有界阻塞隊列;

linkedBlockingQueue基于鏈表的無界阻塞隊列;

synchronousQueue最多只有1個元素的同步隊列, 隊列容量是1;

priorityBlockingQueue帶優先級的無界阻塞隊列,出隊元素是優先級最高或最低的元素;

DelayQueue 帶延遲功能的無界阻塞隊列, 過期元素才會出隊,隊頭元素是快要過期的元素.

以上幾個Queue都是BlockingQueue的實現類

threadFactory

創建線程的工廠,

jdk提供了DefaultThreadFactory默認工廠,

用Executors.defaultThreadFactory()就行.

RejectedExecutionHandler拒絕策略

當隊列滿且線程數達到maximunPoolSize最大線程數后采取的策略, 可傳入

AbortPolicy 拋出異常,這個是默認策略.

CallersRunPolicy 由調用者所在的線程執行任務

DiscardOldestPolicy 丟棄最老的任務

DiscardPolicy 丟棄新任務,不拋出異常

jdk提供的Executors快速創建線程池的用法

jdk封裝了一個Executors類可以直接創建各種線程池,

用法形如

ExecutorService pool = Executors.newXXXXXPool()

可以用Executors類創建業務常用的3種線程池

固定線程池

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }

創建一個核心線程數和最大線程數相同的線程池,都為nThreads,

且線程池的阻塞隊列長度是Integer.MAX_VALUE,

且keepAliveTime=0,說明只要線程個數比核心線程個數多并且當前空閑則回收.

單線程線程池

public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

創建一個核心線程數和最大線程數都是1的線程池,

且線程池的阻塞隊列長度是Integer.MAX_VALUE,

且keepAliveTime=0,說明只要線程個數比核心線程個數多并且當前空閑則回收.

已緩存的線程池

public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }

創建一個按需創建線程的線程池,初始線程個數為0,最多線程個數為

Integer.MAX_VALUE,并且阻塞隊列為同步隊列.

keepAliveTime=60,說明當前線程在60s內空閑則回收.

CachedThreadPool的特殊之處在于,加入同步隊列的任務會被馬上執行,同步隊列里邊最多只有1個任務.

使用創建好的ExecutorService 線程池執行異步任務

jdk線程池怎么實現

submit操作

提交一個任務, 任務參數可以是 Runnable實現類 或 Callable 實現類.

返回的類型是Future 表示異步計算的結果, 可以用future.get()方法拿到數據.

shutdown操作

調用shutdown方法后,線程池就不會再接受新的任務了,但是工作隊列里邊的任務還是要執行的, 該方法會立刻返回,不等待隊列任務完成再返回.

使用線程池的情況下當程序結束時記得調用shutdown關閉線程池, 如果不關閉線程池,則會導致 線程池資源一直不被釋放.

shutdownNow操作

調用shutdownNow方法后,線程池就不會再接受新的任務了,并且會丟棄工作隊列里邊的任務,正在執行的任務會被中斷,該方法會立刻返回,并不等待激活的任務執行完成. 返回值為這時候隊列里面被丟棄的任務列表.

awaitTermination操作

當線程調用awaitTermination方法后,當前線程會被阻塞, 直到線程池狀態變為TERMINATED 才返回,或者等待時間超時才返回.

案例1-測試FixedThreadPool執行CallableTask任務

package cn.demo;

import cn.hutool.core.util.RandomUtil;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class ExecutorTestsForCallableTask {

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        String res1 = "";
        String res2 = "";
        String res3 = "";
        String res4 = "";

        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

        //submit 提交4個任務, 實際執行時,任務是并發執行的,執行順序不固定
        Future<String> submit1 = fixedThreadPool.submit(
                new TestCallableTask(RandomUtil.randomInt(30,1000),"t1"));
        Future<String> submit2 = fixedThreadPool.submit(
                new TestCallableTask(RandomUtil.randomInt(100,400),"t2"));
        Future<String> submit3 = fixedThreadPool.submit(
                new TestCallableTask(RandomUtil.randomInt(30,350),"t3"));
        Future<String> submit4 = fixedThreadPool.submit(
                new TestCallableTask(RandomUtil.randomInt(310,500),"t4"));

        res1 = submit1.get();
        System.out.println(res1);
        res2 = submit2.get();
        System.out.println(res2);
        res3 = submit3.get();
        System.out.println(res3);
        res4 = submit4.get();
        System.out.println(res4);

        fixedThreadPool.shutdown();
    }
}
package cn.demo;


import cn.hutool.core.util.RandomUtil;

import java.time.LocalDateTime;
import java.util.concurrent.Callable;

public class TestCallableTask implements Callable<String> {

    private int testIntVal;
    private String taskSeq;

    public TestCallableTask(int testIntVal, String taskSeq) {
        this.testIntVal = testIntVal;
        this.taskSeq = taskSeq;
    }

    @Override
    public  String call() throws Exception {
        String s = LocalDateTime.now().toString();
        System.out.println(s+"->"+taskSeq+" run ....");

        int i = testIntVal;
        System.out.println(i);

        try {
            Thread.sleep(RandomUtil.randomInt(100,300));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        if (i>300){
            return "300more";
        }else {
            return "300less";
        }
    }
}

案例2-測試FixedThreadPool執行RunnableTask任務

package cn.demo;

import java.util.concurrent.*;

public class ExecutorTestsForRunnableTask {

    public static void main(String[] args) throws ExecutionException, InterruptedException {

        String res1 = "";
        String res2 = "";
        String res3 = "";
        String res4 = "";
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);

        //submit 提交4個任務, 實際執行時,任務是并發執行的,執行順序不固定
        Task1Param task1Param = new Task1Param();
        task1Param.setUrl("f23r3r");
        task1Param.setName("1heg43t34t34t");
        Future<String> stringFuture = fixedThreadPool.submit(
            new TestTask1Runnable(task1Param), "success1 ok");

        Task1Param t2 = new Task1Param();
        t2.setUrl("gnsg2323");
        t2.setName("2wwswer2r1asdaaws");
        Future<String> f2 = fixedThreadPool.submit(new TestTask1Runnable(t2), "success2 ok");

        Task1Param t3 = new Task1Param();
        t3.setUrl("thwasr23r");
        t3.setName("3erzawfe23rawsf");
        Future<String> f3 = fixedThreadPool.submit(new TestTask1Runnable(t3), "success3 ok");

        Task1Param t4 = new Task1Param();
        t4.setUrl("mjkdsragt");
        t4.setName("4tbertydraewrsfk");
        Future<String> f4 = fixedThreadPool.submit(new TestTask1Runnable(t4), "success4 ok");


        res1 = stringFuture.get();
        System.out.println(res1);
        res2 = f2.get();
        System.out.println(res2);
        res3 = f3.get();
        System.out.println(res3);
        res4 = f4.get();
        System.out.println(res4);

        fixedThreadPool.shutdown();
    }
}
package cn.demo;

import cn.hutool.core.util.RandomUtil;
import java.time.LocalDateTime;

public class TestTask1Runnable implements Runnable{

    private Task1Param task1Param;

    public TestTask1Runnable(Task1Param task1Param) {
        this.task1Param = task1Param;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(RandomUtil.randomInt(200,600));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(task1Param.getName());
        System.out.println(task1Param.getUrl());
        String s = LocalDateTime.now().toString();
        System.out.println(s+" TestTask1Runnable run ....");
    }
}

使用自定義的ThreadPoolExecutor來執行異步任務

package cn.demo;


import cn.hutool.core.util.RandomUtil;
import java.util.concurrent.*;

public class TpeTest {

    private final static ThreadPoolExecutor pool =
            new ThreadPoolExecutor(
                    1,1,
                    1L, TimeUnit.MINUTES,
                    new ArrayBlockingQueue<Runnable>(1),
                    new ThreadPoolExecutor.CallerRunsPolicy());
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Future<String> submit1 = pool.submit(
                new TestCallableTask(RandomUtil.randomInt(30,1000),"t1"));
        Future<String> submit2 = pool.submit(
                new TestCallableTask(RandomUtil.randomInt(100,400),"t2"));
        Future<String> submit3 = pool.submit(
                new TestCallableTask(RandomUtil.randomInt(30,350),"t3"));
        Future<String> submit4 = pool.submit(
                new TestCallableTask(RandomUtil.randomInt(310,500),"t4"));
        System.out.println("task1-"+submit1.get());
        System.out.println("task2-"+submit2.get());
        System.out.println("task3-"+submit3.get());
        System.out.println("task4-"+submit4.get());

        pool.shutdown();
    }
}

線程池使用FutureTask時需要注意的事情

線程池使用FutureTask時,如果把拒絕策略設置為 DiscardPolicy 和 DiscardOldestPolicy,并且在被拒絕的任務的Future對象上調用了無參get方法,那么調用線程會一直被阻塞.

如上面的代碼,如果把CallerRunsPolicy替換成 DiscardPolicy 或 DiscardOldestPolicy ,就會導致任務一直被阻塞,一直無法取到future.get()的值.

“jdk線程池怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

jdk
AI

洮南市| 景洪市| 桐城市| 灌阳县| 南雄市| 双辽市| 崇文区| 睢宁县| 东阿县| 吉林省| 临猗县| 恭城| 嵩明县| 九江市| 微博| 江陵县| 马龙县| 奇台县| 汾西县| 资兴市| 邛崃市| 和田县| 阿尔山市| 临朐县| 边坝县| 英超| 金坛市| 郎溪县| 宣城市| 建德市| 溧水县| 固镇县| 石楼县| 皮山县| 广州市| 平湖市| 高碑店市| SHOW| 郸城县| 上虞市| 沐川县|