Skip to content

Commit cf83964

Browse files
committed
添加简易版本线程池封装
1 parent 214a5a2 commit cf83964

File tree

17 files changed

+467
-44
lines changed

17 files changed

+467
-44
lines changed

.idea/compiler.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

EasyExecutor/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

EasyExecutor/build.gradle

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
plugins {
2+
id 'com.android.library'
3+
}
4+
apply from: rootProject.projectDir.absolutePath + "/yc.gradle"
5+
6+
7+
android {
8+
compileSdkVersion rootProject.ext.android["compileSdkVersion"]
9+
//buildToolsVersion rootProject.ext.android["buildToolsVersion"]
10+
defaultConfig {
11+
minSdkVersion rootProject.ext.android["minSdkVersion"]
12+
targetSdkVersion rootProject.ext.android["targetSdkVersion"]
13+
versionCode rootProject.ext.android["versionCode"]
14+
versionName rootProject.ext.android["versionName"]
15+
}
16+
17+
buildTypes {
18+
release {
19+
minifyEnabled false
20+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
21+
}
22+
}
23+
compileOptions {
24+
sourceCompatibility JavaVersion.VERSION_1_8
25+
targetCompatibility JavaVersion.VERSION_1_8
26+
}
27+
}
28+
29+
dependencies {
30+
implementation fileTree(dir: 'libs', include: ['*.jar'])
31+
implementation(rootProject.ext.dependencies["appcompat"])
32+
implementation(rootProject.ext.dependencies["annotation"])
33+
}

EasyExecutor/consumer-rules.pro

Whitespace-only changes.

EasyExecutor/proguard-rules.pro

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.yc.easyexecutor">
4+
5+
</manifest>
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.yc.easyexecutor;
2+
3+
import androidx.annotation.NonNull;
4+
import androidx.annotation.RestrictTo;
5+
6+
/**
7+
* <pre>
8+
* @author yangchong
9+
10+
* time : 2019/5/11
11+
* desc : 抽象task任务类
12+
* revise :
13+
* GitHub : https://github.com/yangchong211/YCThreadPool
14+
* </pre>
15+
*/
16+
@RestrictTo(RestrictTo.Scope.LIBRARY)
17+
public abstract class AbsTaskExecutor {
18+
19+
public abstract void executeOnDiskIO(@NonNull Runnable runnable);
20+
21+
public abstract void executeOnCpu(@NonNull Runnable runnable);
22+
23+
public abstract void postToMainThread(@NonNull Runnable runnable);
24+
25+
public void executeOnMainThread(@NonNull Runnable runnable) {
26+
if (isMainThread()) {
27+
runnable.run();
28+
} else {
29+
postToMainThread(runnable);
30+
}
31+
}
32+
33+
public abstract boolean isMainThread();
34+
}
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
package com.yc.easyexecutor;
2+
3+
import android.os.Handler;
4+
import android.os.Looper;
5+
6+
import androidx.annotation.NonNull;
7+
import androidx.annotation.Nullable;
8+
import androidx.annotation.RestrictTo;
9+
10+
import java.util.concurrent.BlockingQueue;
11+
import java.util.concurrent.ExecutorService;
12+
import java.util.concurrent.Executors;
13+
import java.util.concurrent.LinkedBlockingQueue;
14+
import java.util.concurrent.RejectedExecutionHandler;
15+
import java.util.concurrent.ThreadFactory;
16+
import java.util.concurrent.ThreadPoolExecutor;
17+
import java.util.concurrent.TimeUnit;
18+
import java.util.concurrent.atomic.AtomicLong;
19+
20+
/**
21+
* <pre>
22+
* @author yangchong
23+
24+
* time : 2019/5/11
25+
* desc : task具体实现类
26+
* revise :
27+
* GitHub : https://github.com/yangchong211/YCThreadPool
28+
* </pre>
29+
*/
30+
@RestrictTo(RestrictTo.Scope.LIBRARY)
31+
public class DefaultTaskExecutor extends AbsTaskExecutor {
32+
33+
private final Object mLock = new Object();
34+
@Nullable
35+
private volatile Handler mMainHandler;
36+
/**
37+
* IO 密集型任务的线程池
38+
*/
39+
private final ExecutorService mDiskIO;
40+
/**
41+
* CPU 密集型任务的线程池
42+
*/
43+
private final ThreadPoolExecutor mCPUThreadPoolExecutor;
44+
/**
45+
* CPU 核数
46+
*/
47+
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
48+
/**
49+
* 线程池线程数
50+
*/
51+
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 5));
52+
/**
53+
* 线程池线程数的最大值
54+
*/
55+
private static final int MAXIMUM_POOL_SIZE = CORE_POOL_SIZE;
56+
/**
57+
* 线程空置回收时间
58+
*/
59+
private static final int KEEP_ALIVE_SECONDS = 5;
60+
/**
61+
* 线程池队列
62+
*/
63+
private final BlockingQueue<Runnable> mPoolWorkQueue = new LinkedBlockingQueue<>();
64+
/**
65+
* 这个是为了保障任务超出BlockingQueue的最大值,且线程池中的线程数已经达到MAXIMUM_POOL_SIZE时候
66+
* 还有任务到来会采取任务拒绝策略,这里定义的策略就是再开一个缓存线程池去执行。
67+
* 当然BlockingQueue默认的最大值是int_max,所以理论上这里是用不到的
68+
*/
69+
private final RejectedExecutionHandler mHandler = new RejectedExecutionHandler() {
70+
@Override
71+
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
72+
Executors.newCachedThreadPool().execute(r);
73+
}
74+
};
75+
76+
public DefaultTaskExecutor() {
77+
mDiskIO = Executors.newFixedThreadPool(4, new ThreadFactory() {
78+
79+
private final AtomicLong mCount = new AtomicLong(0);
80+
81+
@Override
82+
public Thread newThread(@NonNull Runnable r) {
83+
return new Thread(r, "LoggerTask #" + mCount.getAndIncrement());
84+
}
85+
});
86+
mCPUThreadPoolExecutor = new ThreadPoolExecutor(
87+
CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE_SECONDS, TimeUnit.SECONDS,
88+
mPoolWorkQueue, Executors.defaultThreadFactory(), mHandler);
89+
mCPUThreadPoolExecutor.allowCoreThreadTimeOut(true);
90+
}
91+
92+
93+
@Override
94+
public void executeOnDiskIO(Runnable runnable) {
95+
if (runnable != null && mDiskIO != null) {
96+
mDiskIO.execute(runnable);
97+
}
98+
}
99+
100+
@Override
101+
public void executeOnCpu(@NonNull Runnable runnable) {
102+
if (runnable != null && mCPUThreadPoolExecutor != null) {
103+
mCPUThreadPoolExecutor.execute(runnable);
104+
}
105+
}
106+
107+
@Override
108+
public void postToMainThread(Runnable runnable) {
109+
if (mMainHandler == null) {
110+
synchronized (mLock) {
111+
if (mMainHandler == null) {
112+
mMainHandler = new Handler(Looper.getMainLooper());
113+
}
114+
}
115+
}
116+
if (mMainHandler != null && runnable != null) {
117+
mMainHandler.post(runnable);
118+
}
119+
}
120+
121+
@Override
122+
public boolean isMainThread() {
123+
return Looper.getMainLooper().getThread() == Thread.currentThread();
124+
}
125+
126+
127+
}

0 commit comments

Comments
 (0)