gpt4 book ai didi

Java(Android)多线程进程

转载 作者:搜寻专家 更新时间:2023-10-30 20:00:34 24 4
gpt4 key购买 nike

我正在开发创建多线程的应用程序(Matt 的 traceroute windows 版本 http://winmtr.net/),每个线程都有自己的进程(执行 ping 命令)。 ThreadPoolExecutor 一段时间后(例如 10 秒)关闭所有线程

ThreadPoolExecutor 使用阻塞队列(在任务执行前保持任务)

int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(
NUMBER_OF_CORES * 2, NUMBER_OF_CORES * 2 + 2, 10L, TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>()
);

PingThread.java

private class PingThread extends Thread {

@Override
public void run() {
long pingStartedAt = System.currentTimeMillis();
// PingRequest is custom object
PingRequest request = buildPingRequest(params);

if (!isCancelled() && !Thread.currentThread().isInterrupted()) {

// PingResponse is custom object

// Note:
// executePingRequest uses PingRequest to create a command
// which than create a runtime process to execute ping command
// using string response i am creating PingResponse

PingResponse pingResponse = PingUtils.executePingRequest(request);

if (pingResponse != null) {
pingResponse.setHopLocation(hopLocation);
// publish ping response to main GUI/handler
publishProgress(pingResponse);
} else
Logger.error(
"PingThread", "PingResponse isNull for " + request.toString()
);
}
}
}

现在如果我创建多个线程,比如在一个循环中超过 500 个并在池执行器中执行

执行线程

PingThread thread = new PingThread(params);
poolExecutor.execute(thread);

我确实知道 LinkedBlockingQueue 在任务执行之前保存任务。每个线程的进程最多需要200到400ms,但一般小于10ms

我在做什么

for (int iteration = 1; iteration <= 50/*configurable*/; iteration++) {

for (int index = 0; index < 10/*configurable*/; index++) {
PingThread thread = new PingThread(someParams);
poolExecutor.execute(thread);
}

try {
Thread.sleep(500);
} catch (InterruptedException e) {
Logger.error(false, e);
}
}

50 次迭代将花费大约 25 秒,这里我只有最多 40 个 ping 响应其余被视为由于超时而丢失。如果我增加迭代,损失也会增加(由于线程数量的增加呈指数增长)

观察:

我在 Galaxy S6 上运行这个应用程序,它有 8 个内核,应用程序池大小为 16,最大池大小为 16 + 2,我知道处理器一次只运行一个线程,它共享并行的量子时间处理。

通过及时观察ThreadPoolExecutor,我看到队列中有很多任务,超时后由于LinkedBlockingQueue

还有很多线程在队列中

如果我减少线程数它工作正常但如果增加它会产生问题

问题:

  • 当我使用带有双核处理器的设备时,Ping 响应会降低。
  • 为什么队列中有很多线程,每个线程占用大约 10 到 50 毫秒(增加线程时间将增加 uptp 300 毫秒或更多)?
  • 它应该在给定的时间内完成,为什么没有?
  • 如何克服这个问题?
  • 我应该使用 ConcurrentLinkedQueue 但它使用生产者/消费者模型,不知何故 ThreadPoolExecutor(我认为是)也使用这个模型。
  • LinkedBlockingQueue 在任务执行之前保留任务(线程空闲或在队列中),如何克服这个问题?
  • 通过为后面的迭代设置 Thread.MAX_PRIORITY 并不能解决问题(后面迭代的线程在队列中)
  • 减少线程数可以解决问题,为什么?因为队列中没有线程?
  • 有什么方法可以检查队列中的线程是否接受它们然后执行其他线程,而不会阻塞其他线程但在给定时间内。
  • 增加 5 秒之类的额外时间不是解决方案
  • How to get the ThreadPoolExecutor to increase threads to max before queueing? 中那样更改 corePoolSize在我的情况下不起作用。

在测试期间,内存和处理器的使用是有限制的。

需要详细的回答/帮助。

编辑

当应用程序进入后台时,没有任何损失,用户 CPU 使用率下降到 0-2%,而焦点应用程序占用 4-6% 的 CPU 使用率。是不是因为 UI 和其他问题,我试图删除所有不必要的代码,我也确实将 PingThread 更改为 PingTask

PingTask 实现 Runnable {/*....*/>

注意:我使用相同的代码创建了单独的基于 Java 的应用程序,它在桌面上运行良好,所以我们可以说这是 Android 操作系统的特定问题吗?

最佳答案

我不确定这是否是导致所有问题的原因,但您正在创建大量不必要的线程。

你应该更换

private class PingThread extends Thread {

与:

private class PingThread implements Runnable {

或(使用更恰当的名称):

private class PingTask implements Runnable {

即提交给 Executor 的任务本身不应该是线程。它有效,因为 Thread 实现了 Runnable,但你在浪费它。

关于Java(Android)多线程进程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40808734/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com