我是靠谱客的博主 俊秀香菇,最近开发中收集的这篇文章主要介绍多线程并发提升性能的三种实现方式Future、CountDownLatch、Semaphore,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

    • 前言
    • 线程池Future实现方式
    • 计数器CountDownLatch实现方式
    • 信号量Semaphore实现方式

前言

我们在应用开发时往往会涉及到当主流程需要执行多个子流程导致运行效率较低的情况。
此时如果多个子流程之间彼此不关联时,可以使用多线程来优化代码。

如主流程A,依次执行子流程a、b、c时,总时间为a+b+c,但是如果我们使用多线程分开执行a、b、c时,理论上总时间可以控制为其中执行最大的时间,这样可以大大节省时间

本文介绍实现上述功能的三种方式

线程池Future实现方式

代码实现:

public static void future() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        Future f1 = executorService.submit(()->{
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程1执行");
        });
        Future f2 = executorService.submit(()->{
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("线程2执行");
        });

        // 当线程1和线程2都完成后再执行后面的逻辑
        f1.get(); // 阻塞,知道f1的线程执行完成
        f2.get(); // 阻塞,知道f2的线程执行完成
        System.out.println("线程1和线程2都执行完成了");
    }

计数器CountDownLatch实现方式

代码实现:

public static void countDownLatch() throws InterruptedException {
        // 定义一个计数器
        CountDownLatch countDownLatch = new CountDownLatch(2);
        new Thread(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("线程1执行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        }).start();
        new Thread(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("线程2执行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                countDownLatch.countDown();
            }
        }).start();
        // 阻塞,直到计数器为0,这里根据业务可以加超时时间,避免出现异常情况,
        // 需要注意避免某个线程报错了导致没有调用countDown,即最好在线程里面finally里面执行
        long start = System.currentTimeMillis();
        countDownLatch.await(3000,TimeUnit.MILLISECONDS);
        long end = System.currentTimeMillis();
        if(end - start > 3000) {
            System.out.println("超时了,业务停止");
        } else {
            System.out.println("线程1和线程2都执行完成了");
        }

    }

信号量Semaphore实现方式

代码实现:

  public static void semaphore() throws InterruptedException {
        int threadCount = 2;
        Semaphore semaphore = new Semaphore(-threadCount+1);
        new Thread(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("线程1执行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 释放1个限号量
                semaphore.release();
            }
        }).start();
        new Thread(() -> {
            try {
                Thread.sleep(2000);
                System.out.println("线程2执行");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                // 释放1个限号量
                semaphore.release();
            }
        }).start();
        // 阻塞,知道semaphore的值为1以上,即2个线程都释放了一个信号量,信号量才为1,
        semaphore.acquire();
        System.out.println("线程1和线程2执行完成");
    }
  public static void main(String[] args) throws InterruptedException, ExecutionException {
        // 让两个线程完成后再执行主线程代码

        // 方式1,基于线程池Future
        future();

        // 方式2,基于计数器CountDownLatch
        countDownLatch();

        // 访视3,基于信号量Semaphore
        semaphore();

    }

最后

以上就是俊秀香菇为你收集整理的多线程并发提升性能的三种实现方式Future、CountDownLatch、Semaphore的全部内容,希望文章能够帮你解决多线程并发提升性能的三种实现方式Future、CountDownLatch、Semaphore所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(73)

评论列表共有 0 条评论

立即
投稿
返回
顶部