不应用默认 AsyncTask 线程优先级 (BACKGROUND)
Default AsyncTask thread priority (BACKGROUND) is not applied
在默认的异步任务构造函数源代码中,我们有以下代码,它将线程优先级设置为 Process.THREAD_PRIORITY_BACKGROUND = 10
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
我创建了一个示例应用程序,我在其中创建了简单的异步任务,并在 doInBackground() 中通过
记录了线程优先级
Log.d("@@@ AsyncTask", "Thread name = " + Thread.currentThread().getName() + "Tread priority " + Thread.currentThread().getPriority());
预期结果:
com.example.myapplication D/@@@ AsyncTask: Thread name = AsyncTask #1Tread priority 10
实际结果:
com.example.myapplication D/@@@ AsyncTask: Thread name = AsyncTask #1Tread priority 5
后台线程的线程优先级与主线程优先级相同
com.example.myapplication D/@@@ MainActivity onCreate: Thread name = mainTread priority 5
我在 API 19 和 API 26 上测试过这个。结果是一样的。
为什么异步任务没有应用后台线程优先级?
还是我阅读优先级的方法不对?
我可以上传资源到github,但是没有太多可以上传的。只有 AsyncTask 和日志语句。
来自 Process.setThreadPriority
的 javadoc:
Set the priority of the calling thread
AsyncTask.execute()
方法在默认 Executor
中执行 AsyncTask.doInBackground()
。 Executor
管理线程池并允许您将任务提交给其中一个线程。为 Executor
创建线程的 class 是 ThreadFactory
。您需要在 Executor
和 ThreadFactory
上执行,以创建具有所需优先级的线程。
class PriorityThreadFactory(
namePrefix: String,
private val threadPriority: Int = Thread.NORM_PRIORITY
) : ThreadFactory {
private val group: ThreadGroup = System.getSecurityManager()?.threadGroup ?: Thread.currentThread().threadGroup
private val threadNumber = AtomicInteger(1)
private val namePrefix: String = "pool-$namePrefix-thread-"
override fun newThread(r: Runnable): Thread {
val t = Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0)
if (t.isDaemon) {
t.isDaemon = false
}
if (t.priority != threadPriority) {
t.priority = threadPriority
}
return t
}
}
因此,当您执行 AsyncTask 时,您将传递使用 PriorityThreadFactory
.
的 Executor
val executor = Executors.newSingleThreadExecutor(PriorityThreadFactory("asynctask", Process.THREAD_PRIORITY_BACKGROUND)
asyncTask.executeOnExecutor(executor)
原来我获取线程优先级的方法是错误的。
获得线程优先级的正确方法是Process.getThreadPriority(Process.myTid())
在默认的异步任务构造函数源代码中,我们有以下代码,它将线程优先级设置为 Process.THREAD_PRIORITY_BACKGROUND = 10
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
mTaskInvoked.set(true);
Result result = null;
try {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
//noinspection unchecked
result = doInBackground(mParams);
Binder.flushPendingCommands();
} catch (Throwable tr) {
mCancelled.set(true);
throw tr;
} finally {
postResult(result);
}
return result;
}
};
我创建了一个示例应用程序,我在其中创建了简单的异步任务,并在 doInBackground() 中通过
记录了线程优先级Log.d("@@@ AsyncTask", "Thread name = " + Thread.currentThread().getName() + "Tread priority " + Thread.currentThread().getPriority());
预期结果:
com.example.myapplication D/@@@ AsyncTask: Thread name = AsyncTask #1Tread priority 10
实际结果:
com.example.myapplication D/@@@ AsyncTask: Thread name = AsyncTask #1Tread priority 5
后台线程的线程优先级与主线程优先级相同
com.example.myapplication D/@@@ MainActivity onCreate: Thread name = mainTread priority 5
我在 API 19 和 API 26 上测试过这个。结果是一样的。
为什么异步任务没有应用后台线程优先级? 还是我阅读优先级的方法不对?
我可以上传资源到github,但是没有太多可以上传的。只有 AsyncTask 和日志语句。
来自 Process.setThreadPriority
的 javadoc:
Set the priority of the calling thread
AsyncTask.execute()
方法在默认 Executor
中执行 AsyncTask.doInBackground()
。 Executor
管理线程池并允许您将任务提交给其中一个线程。为 Executor
创建线程的 class 是 ThreadFactory
。您需要在 Executor
和 ThreadFactory
上执行,以创建具有所需优先级的线程。
class PriorityThreadFactory(
namePrefix: String,
private val threadPriority: Int = Thread.NORM_PRIORITY
) : ThreadFactory {
private val group: ThreadGroup = System.getSecurityManager()?.threadGroup ?: Thread.currentThread().threadGroup
private val threadNumber = AtomicInteger(1)
private val namePrefix: String = "pool-$namePrefix-thread-"
override fun newThread(r: Runnable): Thread {
val t = Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0)
if (t.isDaemon) {
t.isDaemon = false
}
if (t.priority != threadPriority) {
t.priority = threadPriority
}
return t
}
}
因此,当您执行 AsyncTask 时,您将传递使用 PriorityThreadFactory
.
Executor
val executor = Executors.newSingleThreadExecutor(PriorityThreadFactory("asynctask", Process.THREAD_PRIORITY_BACKGROUND)
asyncTask.executeOnExecutor(executor)
原来我获取线程优先级的方法是错误的。
获得线程优先级的正确方法是Process.getThreadPriority(Process.myTid())