package com.hdl.sdk.sourceos.utils.thread;
|
|
import android.os.Handler;
|
import android.os.Looper;
|
import android.util.ArrayMap;
|
|
import java.util.Timer;
|
import java.util.TimerTask;
|
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.Executors;
|
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.RejectedExecutionHandler;
|
import java.util.concurrent.ScheduledExecutorService;
|
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
|
/**
|
* Created by Tong on 2021/10/21.
|
*/
|
public class ThreadUtils {
|
|
private static final Handler uiHandler = new Handler(Looper.getMainLooper());
|
|
private static final ArrayMap<Integer, ExecutorService> mThreadPools = new ArrayMap<>();
|
|
//后台处理线程池
|
private static final int IO_TYPE = 0;
|
|
//分发线程池
|
private static final int DISPENSE_TYPE = 1;
|
|
private static final Timer TIMER = new Timer();
|
|
//cpu 最大线程容纳量
|
private static final int coreSize = Runtime.getRuntime().availableProcessors() + 1;
|
private static final int maxCoreSize = 2 * Runtime.getRuntime().availableProcessors() + 1;
|
|
|
private volatile static ThreadUtils INSTANCE = null;
|
|
private ThreadUtils() {
|
}
|
|
public static ThreadUtils getInstance() {
|
if (INSTANCE == null) {
|
synchronized (ThreadUtils.class) {
|
if (INSTANCE == null) {
|
INSTANCE = new ThreadUtils();
|
}
|
}
|
}
|
return INSTANCE;
|
}
|
|
|
/**
|
* @return 单线程,无限长度队列,会在调用线程执行,频繁用到这个线程说明并发超级多
|
*/
|
private ExecutorService getSingleThread() {
|
if (!mThreadPools.isEmpty() && mThreadPools.containsKey(DISPENSE_TYPE)) {
|
ExecutorService thread = mThreadPools.get(DISPENSE_TYPE);
|
if (thread != null && !thread.isShutdown()) {
|
return thread;
|
}
|
}
|
final ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(), new RenameThreadFactory() {
|
|
@Override
|
public String getName(int poolNumber, int threadNumber) {
|
return "app_dispense_" + poolNumber + "_" + threadNumber;
|
}
|
}, new ThreadPoolExecutor.DiscardPolicy());
|
|
poolExecutor.allowCoreThreadTimeOut(true);
|
|
mThreadPools.put(DISPENSE_TYPE, poolExecutor);
|
return poolExecutor;
|
}
|
|
/**
|
* 维护 cpu 最大线程容纳量+队列1024 用完在单线程调用
|
*/
|
private ExecutorService getIOThread() {
|
if (!mThreadPools.isEmpty() && mThreadPools.containsKey(IO_TYPE)) {
|
ExecutorService thread = mThreadPools.get(IO_TYPE);
|
if (thread != null && !thread.isShutdown()) {
|
return thread;
|
}
|
}
|
final ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(coreSize, coreSize, 30, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1024), new RenameThreadFactory() {
|
@Override
|
public String getName(int poolNumber, int threadNumber) {
|
return "app_io_" + poolNumber + "_" + threadNumber;
|
}
|
//满了,就使用备份线程池,会oom,使用task会捕抓异常
|
}, new BackgroundRunsPolicy());
|
|
poolExecutor.allowCoreThreadTimeOut(true);
|
|
mThreadPools.put(IO_TYPE, poolExecutor);
|
return poolExecutor;
|
}
|
|
|
/**
|
* 线程数量固定的线程池
|
*/
|
public static ExecutorService newFixedThreadPool(int size) {
|
if (size == 0 || coreSize < size) {
|
return Executors.newFixedThreadPool(coreSize);
|
}
|
return Executors.newFixedThreadPool(size);
|
}
|
|
/**
|
* 定时任务线程池
|
*/
|
public static ScheduledExecutorService newScheduledThreadPool(int size) {
|
if (size == 0 || coreSize < size) {
|
return Executors.newScheduledThreadPool(coreSize);
|
}
|
return Executors.newScheduledThreadPool(size);
|
}
|
|
|
/**
|
* 切换回主线程
|
*/
|
public static void runOnUiThread(Runnable run) {
|
if (Looper.getMainLooper() == Looper.myLooper()) {
|
try {
|
run.run();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
} else {
|
try {
|
uiHandler.post(new Runnable() {
|
@Override
|
public void run() {
|
try {
|
run.run();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
});
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
}
|
}
|
|
/**
|
* 延时更新Ui
|
*/
|
public static void runOnUiThreadDelay(Runnable run, long delayMillis) {
|
uiHandler.postDelayed(new Runnable() {
|
@Override
|
public void run() {
|
try {
|
run.run();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
}, delayMillis);
|
}
|
|
|
/**
|
* 后台耗时任务
|
*/
|
public static void runAsyncThread(Runnable run) {
|
try {
|
getInstance().getIOThread().execute(new Runnable() {
|
@Override
|
public void run() {
|
try {
|
run.run();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
});
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
|
/**
|
* 删除后台任务
|
*/
|
public static void removeTask(Task task) {
|
if (task == null) {
|
return;
|
}
|
try {
|
task.cancel();
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
}
|
|
|
/**
|
* 有休眠
|
* 后台耗时延迟任务
|
*/
|
public static void runAsyncThread(Runnable run, long time) {
|
try {
|
final TimerTask timerTask = new TimerTask() {
|
@Override
|
public void run() {
|
try {
|
ExecutorService thread = getInstance().getIOThread();
|
if (!thread.isShutdown()) {
|
thread.execute(run);
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
|
}
|
};
|
TIMER.schedule(timerTask, time);
|
} catch (Throwable e) {
|
e.printStackTrace();
|
}
|
|
}
|
|
public abstract static class Task implements ITask {
|
|
private Thread thread;
|
|
public abstract void doInBackground();
|
|
private final AtomicBoolean isCancel = new AtomicBoolean();
|
|
public Task() {
|
isCancel.set(false);
|
}
|
|
@Override
|
public void run() {
|
thread = Thread.currentThread();
|
try {
|
if (!isCancel.get()) {
|
doInBackground();
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
onError(e);
|
}
|
thread = null;
|
}
|
|
public void cancel() {
|
try {
|
isCancel.set(true);
|
if (thread != null) {
|
thread.interrupt();
|
}
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
}
|
|
@Override
|
public void onError(Throwable t) {
|
t.printStackTrace();
|
}
|
}
|
|
|
public interface ITask extends Runnable {
|
void onError(Throwable t);
|
}
|
|
|
public static class BackgroundRunsPolicy implements RejectedExecutionHandler {
|
|
public BackgroundRunsPolicy() {
|
}
|
|
public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {
|
if (!e.isShutdown()) {
|
try {
|
backgroundRun(r);
|
} catch (Exception e1) {
|
if (r instanceof ITask) {
|
((ITask) r).onError(e1);
|
} else {
|
throw e1;
|
}
|
|
}
|
}
|
}
|
|
public void backgroundRun(Runnable runnable) {
|
getInstance().getSingleThread().execute(new Runnable() {
|
@Override
|
public void run() {
|
runnable.run();
|
}
|
});
|
|
}
|
}
|
|
|
}
|