面试的我快被问吐了,我只知道实现方式 但总是忘记 所有这次写这个demo 实际项目中也使用过常用于汇总统计 如果需要更进一步优化 根据功能而定 不需要实时性的可采用定时器来进行执行 ,执行结果放入redis缓存中,从redis中获取速度会更加快速
测试代码
多线程进行并行执行,汇总需要同步执行
- 线程采用线程池方式 并行执行
- 使用CountDownLatch类 (线程计数器) 同步处理
public class ThreadPollUtil {
private static int corePoolSize = Runtime.getRuntime().availableProcessors();
/**
* corePoolSize 用于指定核心线程数量
* maximumPoolSize 指定最大线程数
* keepAliveTime和TimeUnit指定线程空闲后的最大存活时间
*/
public static ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, corePoolSize+1, 10l, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(1000));
/*
让主线程等待 CountDownLatch 任务计数器
countDownLatch这个类使一个线程等待其他线程各自执行完毕后再执行。
是通过一个计数器来实现的,计数器的初始值是线程的数量。每当一个线程执行完毕后,计数器的值就-1,当计数器的值为0时,表示所有线程都执行完毕,然后在闭锁上等待的线程就可以恢复工作了。
*/
public static void main(String[] args) throws InterruptedException {
//创建一个三个子线程 初始化计数器
Map<Object, Object> map = new HashMap<>();
CountDownLatch countDownLatch = new CountDownLatch(3);
Long m=1000000000L;
long time11 = System.currentTimeMillis();
ThreadPollUtil.executor.submit(new Runnable() {
@Override
public void run() {
long time1 = System.currentTimeMillis();
int i=0;
for (int i1 = 0; i1 < m; i1++) {
i=i1+i;
}
map.put("1",i);
//计数器-1
countDownLatch.countDown();
long time2 = System.currentTimeMillis();
System.out.println("线程一"+(time1 - time2) + "毫秒。");
}
});
ThreadPollUtil.executor.submit(new Runnable() {
@Override
public void run() {
long time1 = System.currentTimeMillis();
int i=0;
for (int i1 = 0; i1 < m; i1++) {
i=i1+i;
}
map.put("1",i);
//计数器-1
countDownLatch.countDown();
long time2 = System.currentTimeMillis();
System.out.println("线程二"+(time1 - time2) + "毫秒。");
}
});
ThreadPollUtil.executor.submit(new Runnable() {
@Override
public void run() {
long time1 = System.currentTimeMillis();
int i=0;
for (int i1 = 0; i1 < m; i1++) {
i=i1+i;
}
map.put("1",i);
//计数器-1
countDownLatch.countDown();
long time2 = System.currentTimeMillis();
System.out.println("线程三"+(time1 - time2) + "毫秒。");
}
});
/**
* 通过await方法让主线程等待
*/
countDownLatch.await();
long time22 = System.currentTimeMillis();
System.out.println("总线程"+(time11 - time22) + "毫秒。");
}
}
再做个比较没有使用多线程的自上而下的逻辑
class Xxx{
public static void main(String[] args) throws InterruptedException {
long time1 = System.currentTimeMillis();
int i=0;
Long m=1000000000L;
for (int i1 = 0; i1 < m; i1++) {
i=i1+i;
}
System.out.println("执行一");
for (int i1 = 0; i1 < m; i1++) {
i=i1+i;
}
System.out.println("执行二");
for (int i1 = 0; i1 < m; i1++) {
i=i1+i;
}
System.out.println("执行三");
long time2 = System.currentTimeMillis();
System.out.println("总线程"+(time1 - time2) + "毫秒。");
}
}