parent
e12e7dd30e
commit
3164d646e7
@ -0,0 +1,104 @@
|
|||||||
|
package org.opsli.common.thread;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线程池执行器调用者
|
||||||
|
*
|
||||||
|
* @author Parker
|
||||||
|
* @date 2020-10-08 10:24
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public final class AsyncProcessCoordinator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task 包装类<br>
|
||||||
|
* 此类型的意义是记录可能会被 Executor 吃掉的异常<br>
|
||||||
|
*/
|
||||||
|
public static class TaskWrapper implements Runnable {
|
||||||
|
|
||||||
|
private final Runnable gift;
|
||||||
|
private final CountDownLatch latch;
|
||||||
|
private final AtomicInteger count;
|
||||||
|
|
||||||
|
public TaskWrapper(final Runnable target) {
|
||||||
|
this.gift = target;
|
||||||
|
this.count = null;
|
||||||
|
this.latch = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskWrapper(final Runnable target, final AsyncProcessExecutorByWait.AsyncWaitLock lock) {
|
||||||
|
if(lock == null){
|
||||||
|
this.gift = null;
|
||||||
|
this.count = null;
|
||||||
|
this.latch = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.gift = target;
|
||||||
|
this.count = lock.getCount();
|
||||||
|
this.latch = lock.getLatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// 捕获异常,避免在 Executor 里面被吞掉了
|
||||||
|
if (gift == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 执行任务
|
||||||
|
gift.run();
|
||||||
|
|
||||||
|
if(count != null){
|
||||||
|
// 标示已执行
|
||||||
|
count.decrementAndGet();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
String errMsg = StrUtil.format("线程池-包装的目标执行异常: {}", e.getMessage());
|
||||||
|
log.error(errMsg, e);
|
||||||
|
} finally {
|
||||||
|
if(latch != null){
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 此类型无法实例化
|
||||||
|
*/
|
||||||
|
private AsyncProcessCoordinator(){}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行指定的任务
|
||||||
|
*
|
||||||
|
* @param task 任务
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
protected static boolean execute(final Runnable task) {
|
||||||
|
return AsyncProcessor.executeTask(new TaskWrapper(task));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行指定的任务
|
||||||
|
*
|
||||||
|
* @param task 任务
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
protected static boolean execute(final Runnable task, final AsyncProcessExecutorByWait.AsyncWaitLock lock) {
|
||||||
|
boolean execute = AsyncProcessor.executeTask(new TaskWrapper(task, lock));
|
||||||
|
// 执行任务被拒绝 门闩减1 计数器不动 End
|
||||||
|
if(!execute){
|
||||||
|
lock.getLatch().countDown();
|
||||||
|
}
|
||||||
|
return execute;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package org.opsli.common.thread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步进程 执行器
|
||||||
|
*
|
||||||
|
* @author Parker
|
||||||
|
* @date 2021年7月15日13:43:37
|
||||||
|
*/
|
||||||
|
public interface AsyncProcessExecutor {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存放任务
|
||||||
|
* @param task 任务
|
||||||
|
* @return AsyncProcessExecutor
|
||||||
|
*/
|
||||||
|
AsyncProcessExecutor put(final Runnable task);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行
|
||||||
|
* @return boolean
|
||||||
|
*/
|
||||||
|
boolean execute();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2020 OPSLI 快速开发平台 https://www.opsli.com
|
||||||
|
* <p>
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
package org.opsli.common.thread;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 多线程锁执行器 正常处理
|
||||||
|
*
|
||||||
|
* @author Parker
|
||||||
|
* @date 2020-12-10 10:36
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class AsyncProcessExecutorByNormal implements AsyncProcessExecutor{
|
||||||
|
|
||||||
|
/** 任务队列 */
|
||||||
|
private final List<Runnable> taskList;
|
||||||
|
|
||||||
|
public AsyncProcessExecutorByNormal(){
|
||||||
|
taskList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行
|
||||||
|
* @param task 任务
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public AsyncProcessExecutorByNormal put(final Runnable task){
|
||||||
|
taskList.add(task);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行 线程锁 等待查询结果 结果完成后继续执行
|
||||||
|
*
|
||||||
|
* @return boolean 最终直接结果
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean execute(){
|
||||||
|
if(CollUtil.isEmpty(this.taskList)){
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Runnable task : this.taskList) {
|
||||||
|
// 多线程执行任务
|
||||||
|
AsyncProcessCoordinator.execute(task);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回执行结果
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package org.opsli.common.thread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 异步进程 执行器 工厂
|
||||||
|
*
|
||||||
|
* @author Parker
|
||||||
|
* @date 2021年7月15日13:43:37
|
||||||
|
*/
|
||||||
|
public final class AsyncProcessExecutorFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建等待执行器
|
||||||
|
* @return AsyncProcessExecutor
|
||||||
|
*/
|
||||||
|
public static AsyncProcessExecutor createWaitExecutor(){
|
||||||
|
return new AsyncProcessExecutorByWait();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建正常执行器
|
||||||
|
* @return AsyncProcessExecutor
|
||||||
|
*/
|
||||||
|
public static AsyncProcessExecutor createNormalExecutor(){
|
||||||
|
return new AsyncProcessExecutorByNormal();
|
||||||
|
}
|
||||||
|
|
||||||
|
// =====================
|
||||||
|
|
||||||
|
private AsyncProcessExecutorFactory(){}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package org.opsli.common.thread;
|
||||||
|
|
||||||
|
import cn.hutool.core.thread.ThreadUtil;
|
||||||
|
|
||||||
|
public class Test {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
AsyncProcessExecutor executor = new AsyncProcessExecutorByNormal();
|
||||||
|
for (int i = 0; i < 10000; i++) {
|
||||||
|
int finalI = i;
|
||||||
|
executor.put(()->{
|
||||||
|
ThreadUtil.sleep(1000);
|
||||||
|
System.out.println(finalI);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
boolean execute = executor.execute();
|
||||||
|
System.out.println(execute);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,54 +0,0 @@
|
|||||||
package org.opsli.common.thread.refuse;
|
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义线程有界队列
|
|
||||||
*
|
|
||||||
* @author 一枝花算不算浪漫
|
|
||||||
* @date 2020-10-08 10:24
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class AsyncProcessQueueReFuse {
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
/**
|
|
||||||
* Task 包装类<br>
|
|
||||||
* 此类型的意义是记录可能会被 Executor 吃掉的异常<br>
|
|
||||||
*/
|
|
||||||
public static class TaskWrapper implements Runnable {
|
|
||||||
|
|
||||||
private final Runnable gift;
|
|
||||||
|
|
||||||
public TaskWrapper(final Runnable target) {
|
|
||||||
this.gift = target;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// 捕获异常,避免在 Executor 里面被吞掉了
|
|
||||||
if (gift != null) {
|
|
||||||
try {
|
|
||||||
gift.run();
|
|
||||||
} catch (Exception e) {
|
|
||||||
String errMsg = StrUtil.format("线程池-包装的目标执行异常: {}", e.getMessage());
|
|
||||||
log.error(errMsg, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行指定的任务
|
|
||||||
*
|
|
||||||
* @param task 任务
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static boolean execute(final Runnable task) {
|
|
||||||
return AsyncProcessorReFuse.executeTask(new TaskWrapper(task));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
package org.opsli.common.thread.wait;
|
|
||||||
|
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
import java.util.concurrent.CountDownLatch;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 自定义线程有界队列 - 等待线程执行完毕不拒绝
|
|
||||||
*
|
|
||||||
* @author 一枝花算不算浪漫
|
|
||||||
* @date 2020-10-08 10:24
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class AsyncProcessQueueWait {
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
/**
|
|
||||||
* Task 包装类<br>
|
|
||||||
* 此类型的意义是记录可能会被 Executor 吃掉的异常<br>
|
|
||||||
*/
|
|
||||||
public static class TaskWrapper implements Runnable {
|
|
||||||
|
|
||||||
private final Runnable gift;
|
|
||||||
private final CountDownLatch latch;
|
|
||||||
private final AtomicInteger count;
|
|
||||||
|
|
||||||
public TaskWrapper(final Runnable target, final AtomicInteger count, final CountDownLatch latch) {
|
|
||||||
this.gift = target;
|
|
||||||
this.count = count;
|
|
||||||
this.latch = latch;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// 捕获异常,避免在 Executor 里面被吞掉了
|
|
||||||
if (gift != null) {
|
|
||||||
try {
|
|
||||||
gift.run();
|
|
||||||
// 标示已执行
|
|
||||||
count.decrementAndGet();
|
|
||||||
} catch (Exception e) {
|
|
||||||
String errMsg = StrUtil.format("线程池-包装的目标执行异常: {}", e.getMessage());
|
|
||||||
log.error(errMsg, e);
|
|
||||||
} finally {
|
|
||||||
latch.countDown();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行指定的任务
|
|
||||||
*
|
|
||||||
* @param task 任务
|
|
||||||
* @return boolean
|
|
||||||
*/
|
|
||||||
public static boolean execute(final Runnable task, final AtomicInteger count, final CountDownLatch latch) {
|
|
||||||
return AsyncProcessorWait.executeTask(new TaskWrapper(task, count, latch));
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in new issue