All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dahuatech.hutool.core.thread.SyncFinisher Maven / Gradle / Ivy

package com.dahuatech.hutool.core.thread;

import com.dahuatech.hutool.core.exceptions.NotInitedException;
import com.dahuatech.hutool.core.exceptions.UtilException;

import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;

/**
 * 线程同步结束器
* 在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 * *
 * ps:
 * //模拟1000个线程并发
 * SyncFinisher sf = new SyncFinisher(1000);
 * concurrencyTestUtil.run(() -> {
 *      // 需要并发测试的业务代码
 * });
 * 
* * @author Looly * @since 4.1.15 */ public class SyncFinisher { private Set workers; private int threadSize; private ExecutorService executorService; private boolean isBeginAtSameTime; /** 启动同步器,用于保证所有worker线程同时开始 */ private CountDownLatch beginLatch; /** 结束同步器,用于等待所有worker线程同时结束 */ private CountDownLatch endLatch; /** * 构造 * * @param threadSize 线程数 */ public SyncFinisher(int threadSize) { this.beginLatch = new CountDownLatch(1); this.threadSize = threadSize; this.executorService = ThreadUtil.newExecutor(threadSize); this.workers = new LinkedHashSet<>(); } /** * 设置是否所有worker线程同时开始 * * @param isBeginAtSameTime 是否所有worker线程同时开始 * @return this */ public SyncFinisher setBeginAtSameTime(boolean isBeginAtSameTime) { this.isBeginAtSameTime = isBeginAtSameTime; return this; } /** * 增加定义的线程数同等数量的worker * * @param runnable 工作线程 * @return this */ public SyncFinisher addRepeatWorker(final Runnable runnable) { for (int i = 0; i < this.threadSize; i++) { addWorker( new Worker() { @Override public void work() { runnable.run(); } }); } return this; } /** * 增加工作线程 * * @param runnable 工作线程 * @return this */ public SyncFinisher addWorker(final Runnable runnable) { return addWorker( new Worker() { @Override public void work() { runnable.run(); } }); } /** * 增加工作线程 * * @param worker 工作线程 * @return this */ public synchronized SyncFinisher addWorker(Worker worker) { workers.add(worker); return this; } /** 开始工作 */ public void start() { start(true); } /** * 开始工作 * * @param sync 是否阻塞等待 * @since 4.5.8 */ public void start(boolean sync) { endLatch = new CountDownLatch(workers.size()); for (Worker worker : workers) { executorService.submit(worker); } // 保证所有worker同时开始 this.beginLatch.countDown(); if (sync) { try { this.endLatch.await(); } catch (InterruptedException e) { throw new UtilException(e); } } } /** * 等待所有Worker工作结束,否则阻塞 * * @throws InterruptedException 用户中断 * @deprecated 使用start方法指定是否阻塞等待 */ @Deprecated public void await() throws InterruptedException { if (endLatch == null) { throw new NotInitedException("Please call start() method first!"); } endLatch.await(); } /** 清空工作线程对象 */ public void clearWorker() { workers.clear(); } /** * 剩余任务数 * * @return 剩余任务数 */ public long count() { return endLatch.getCount(); } /** * 工作者,为一个线程 * * @author xiaoleilu */ public abstract class Worker implements Runnable { @Override public void run() { if (isBeginAtSameTime) { try { beginLatch.await(); } catch (InterruptedException e) { throw new UtilException(e); } } try { work(); } finally { endLatch.countDown(); } } public abstract void work(); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy