gpt4 book ai didi

java - 其他线程中的 IO 操作阻塞了我的 UI 线程?

转载 作者:太空宇宙 更新时间:2023-11-03 12:42:40 26 4
gpt4 key购买 nike

为了让 IO 不会阻塞我的 Android 应用程序中的 UI 线程,我正在尝试将文件写入操作移动到一个单独的线程中。这是我用来启动低优先级线程以从字节缓冲区写入大约 1Mb 的代码:

Thread t = new Thread(new Runnable()
{
@Override
public void run()
{
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
try
{
FileOutputStream fos = new FileOutputStream(filename));
try
{
final java.nio.channels.FileChannel outChannel = fos.getChannel();
outChannel.write(byteBuffer);
fos.getFD().sync();
}
finally
{
if (fos != null)
fos.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
});

t.setPriority(Thread.MIN_PRIORITY);
t.start();

当某些 UI 事件发生时,这些线程会在我的应用程序中启动。不幸的是,有时我仍然会注意到大量的滞后。我的用户界面每 10 次左右就会卡住 ~2 秒,我开始/完成上述线程之一。如果我注释掉线程代码,这些延迟就会消失。

我该怎么做才能阻止此 IO 操作阻塞我的 UI 线程?

我不确定现在要做什么来诊断问题。我的理解是,当“outChannel.write”发生时,IO 线程会被阻塞,因为它正在等待 IO 操作完成,这意味着我的 UI 线程会立即接管。写操作实际上需要大量的 CPU 能力吗?

编辑:

启用 StrictView(我确信这是因为它在我首先修复的 UI 线程中发现了一些不相关的 IO 问题),我可以确认我的 IO 线程中没有发生 IO。

运行 traceview 的结果相当令人费解。 UI 问题是,当我执行拖放操作时,每执行 10 次左右,设备似乎会卡住大约 0.5 到 1 秒。你拖动的东西会卡住,经过一段延迟后最终会跳到你手指所在的位置。在 traceview 中,我一直拖放直到发生这种情况。对于在 traceview 中发生这种情况的情况,我的后台线程没有运行,但突然出现大约 1 秒的阻塞,在我的 UI 线程上通常调用速度很快的操作执行时间大约延长了 10 倍。例如,对 .drawBitmap(具有固定大小的位图)的调用显示为需要 ~0.2s 来执行,而在此之前每次相同的 .drawBitamp 调用都需要十分之一的时间。我可能只是读错了,但我不知道从这里去哪里或寻找什么。

最佳答案

What can I do to stop this IO operation from blocking my UI thread?

I/O 操作不会直接阻塞主应用程序线程。您在主应用程序线程上运行的代码正在阻塞主应用程序线程。您需要确定在主应用程序线程上运行的代码在哪里被 bundle 了。为此,请使用调试器或 Log.d() 语句或其他任何东西。

例如,在大多数 Android 设备上,文件系统是 YAFFS2,它具有每个分区的全局锁。引用 Brad Fitzpatrick :

yaffs has a giant lock around the whole filesystem code, so even a tiny stat() can block for seconds if the disk is otherwise being hammered by something else (during boot, heavy sync, etc).

因此,如果您在后台线程中占用文件系统数秒,主应用程序线程将无法执行其自身的文件 I/O。也许这就是让您感到困惑的原因,在这种情况下,Android 2.3 中的 StrictMode 可以帮助您确定问题的根源。

What's the point of moving it to another thread then?

重点是将闪存 I/O 移出主应用程序线程。全闪存 I/O。

FWIW,Android 将出现在 ext4 设备(例如,Nexus S)上,并且这个问题消失了......尽管您随后需要担心 sync() 调用。在 YAFFS2 上,sync() 总的来说不太重要,因为它几乎没有缓冲。

关于java - 其他线程中的 IO 操作阻塞了我的 UI 线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4904276/

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