多線程閉鎖/柵欄/信號量

多線程閉鎖

@Slf4j
public class CountDownLatchTest {

    private static final int poolSize = 4;

    private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("ThreadPoolContainer-thread-%d").build();

    /**
     * 自測多線程閉鎖,當計數器減到0時,表示被計數的線程都已經執行完成,適合與FutureTask一起使用,可以判斷異步執行結果
     * @param args
     */
    public static void main(String[] args) {

        ArrayList<String> demoList = Lists.newArrayList();
        demoList.add("111");
        demoList.add("222");
        demoList.add("333");

        List<List<String>> lists = Lists.partition(demoList, 1);

        //創建線程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, poolSize, 2, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024), THREAD_FACTORY, new ThreadPoolExecutor.AbortPolicy());

        //創建計數器、FutureTask接受每個線程的處理結果
        CountDownLatch latch = new CountDownLatch(lists.size());
        List<FutureTask<Boolean>> taskList = new ArrayList<>();

        //循環開啓線程
        for (List<String> list : lists) {
            FutureTask<Boolean> task = new FutureTask<>(new Callable<Boolean>() {
                @Override
                public Boolean call() {
                    Boolean result = false;
                    try {
                        System.out.println(list + Thread.currentThread().getName());
                        result = true;
                    } finally {
                        latch.countDown();
                    }
                    return result;
                }
            });
            //每次開啓一個線程都加入線程池
            executor.submit(task);
            //每個線程的處理結果放入集合
            taskList.add(task);
        }

        //線程等待
        try {
            //latch.await();//不設置時間就一隻等待知道所有線程都執行完成
            boolean allFinished = latch.await(10, TimeUnit.SECONDS);
            if (!allFinished) {
                log.error("多線程閉鎖等待了10s,仍未執行完畢");
            }
        } catch (InterruptedException e) {
            log.error("線程中斷!", e);
            //通過調用thread.currentThread().interrupt(),可以設置線程的中斷標誌,這樣更高級別的中斷處理程序就會注意到它,並可以適當地處理它。
            Thread.currentThread().interrupt();
        }

        //解析每個線程的執行結果
        for (FutureTask<Boolean> task : taskList) {
            Boolean result = false;
            try {
                result = task.get();
                System.out.println(result + "-" + task);
            } catch (Exception e) {
                log.error("線程中斷!", e);
                //通過調用thread.currentThread().interrupt(),可以設置線程的中斷標誌,這樣更高級別的中斷處理程序就會注意到它,並可以適當地處理它。
                Thread.currentThread().interrupt();
            }
            if(!result){
                System.out.println("多線程閉鎖存在某線程處理異常!");
            }
        }
        //關閉線程池
        executor.shutdown();
    }

}

多線程柵欄

@Slf4j
public class CyclicBarrierTest {

    private static final int poolSize = 5;

    private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("ThreadPoolContainer-thread-%d").build();

    /**
     * 自測-柵欄,當被標記的線程都執行到某一個點時,再執行第二個參數的線程任務,最後執行線程的柵欄點之後的任務
     * @param args
     */
    public static void main(String[] args) {

        ArrayList<String> demoList = Lists.newArrayList();
        demoList.add("111");
        demoList.add("222");
        demoList.add("333");
        demoList.add("444");
        demoList.add("555");


        List<List<String>> lists = Lists.partition(demoList, 1);

        //創建線程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, poolSize, 5, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024), THREAD_FACTORY, new ThreadPoolExecutor.AbortPolicy());


        //創建線程屏障,其它線程執行完成之後再執行Thread.currentThread() 也即主線程
        CyclicBarrier cyclicBarrier = new CyclicBarrier(lists.size(), new Runnable() {
            @Override
            public void run() {
                System.out.println("這個線程打個叉!");
            }
        });

        //循環開啓線程
        for (List<String> list : lists) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println(list + Thread.currentThread().getName());
                    try {
                        cyclicBarrier.await();
                        System.out.println(Thread.currentThread().getName() + "接着執行線程");
                    } catch (InterruptedException | BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                }
            });
            //每次開啓一個線程都加入線程池
            executor.submit(thread);
        }
        //關閉線程池
        executor.shutdown();

    }

}

多線程信號量

@Slf4j
public class SemaphoreTest {

    private static final int poolSize = 5;

    private static final ThreadFactory THREAD_FACTORY = new ThreadFactoryBuilder().setNameFormat("ThreadPoolContainer-thread-%d").build();

    /**
     * 自測-信號量,用來控制流量的  常用於秒殺,搶車位等等
     * @param args
     */
    public static void main(String[] args) {

        ArrayList<String> demoList = Lists.newArrayList();
        demoList.add("111");
        demoList.add("222");
        demoList.add("333");
        demoList.add("444");
        demoList.add("555");
        demoList.add("666");


        List<List<String>> lists = Lists.partition(demoList, 1);

        //創建線程池
        ThreadPoolExecutor executor = new ThreadPoolExecutor(poolSize, poolSize, 5, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(1024), THREAD_FACTORY, new ThreadPoolExecutor.AbortPolicy());

        //一共有三個資源
        Semaphore semaphore = new Semaphore(3);

        //循環開啓線程
        for (List<String> list : lists) {
            Thread task = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName() + "搶到資源");
                        TimeUnit.SECONDS.sleep(3);
                        System.out.println(Thread.currentThread().getName() + "放開資源");
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        semaphore.release();
                    }
                }
            });
            //每次開啓一個線程都加入線程池
            executor.submit(task);
        }

        //關閉線程池
        executor.shutdown();

    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章