使用Executors(线程池执行任务)+CountDownLatch(用于等待执行器中所有任务完成,真是个好东西),快速实现用并发编程来优化串行程序

2020/10/27 10:03
阅读数 150

 

其实现在觉得有了Java并发包的支持后,Java并发编程还是比较容易的。

我们可以将要完成的任务进行合理的拆分,从而用并发程序优化代码执行效率,加上juc提供的执行器Executors(内部是阻塞队列)+CountDownLatch等工具类,可以很快的写出高效的并发程序。

以计算斐波那契为例子:

Fabi.java

package concurrent.fabi;

public class Fabi {
    public static int calFabi(int n) {
        if (n < 2) {
            return 1;
        }
        return calFabi(n - 1) + calFabi(n - 2);
    }

    public static final int taskNum = 20;

    public static final int num = 40;
}

1.串行版本

Serial.java

package concurrent.fabi.serial;

import concurrent.fabi.Fabi;

public class Serial {
    public static void main(String[] args) {
        long startTime = System.currentTimeMillis();

        for (int i = 0; i < Fabi.taskNum; i++) {
            int ret = Fabi.calFabi(Fabi.num);
            System.out.println(ret);
        }

        long costTime = System.currentTimeMillis() - startTime;
        System.out.println("串行耗时:" + costTime);
    }
}

/*
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
串行耗时:8539
 */

2.并行版本

ParaTask.java

package concurrent.fabi.parallel;

import concurrent.fabi.Fabi;

import java.util.concurrent.CountDownLatch;

public class ParaTask implements Runnable {
    private int n;
    private CountDownLatch countDownLatch;

    public ParaTask(int n, CountDownLatch countDownLatch) {
        this.n = n;
        this.countDownLatch = countDownLatch;

    }

    @Override
    public void run() {
        int num = Fabi.calFabi(n);
        System.out.println(num);
        countDownLatch.countDown();
    }
}

Para.java

​
package concurrent.fabi.parallel;

import concurrent.fabi.Fabi;

import java.util.concurrent.*;

public class Para {
    public static void main(String[] args) throws InterruptedException {

        // 执行器
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());

        CountDownLatch countDownLatch = new CountDownLatch(Fabi.taskNum);

        long startTime = System.currentTimeMillis();

        // 搞一些任务
        for (int i = 0; i < Fabi.taskNum; i++) {
            ParaTask paraTask = new ParaTask(Fabi.num, countDownLatch);
            executorService.execute(paraTask);
        }

        countDownLatch.await();
        executorService.shutdown();

        long costTime = System.currentTimeMillis() - startTime;
        System.out.println("并行耗时:" + costTime);
    }
}

/*
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
165580141
并行耗时:4530
 */

​

 

总结:

明白了java提供的并发工具包的用法,那就可以愉快快速开发各种并发程序了。

就是将任务进行合理拆分而已。

比如:游戏中导表工具,就可以并发执行啦!每一个表格是独立的,当然可以独立执行啦。 将导表作为一个个任务,扔到执行器,然后等待完成即可!并发编程确实是一项利器!

 

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部