java - 缓存和线程问题

标签 java android multithreading queue

在我正在开发的这个应用程序中,我正在缓存在线音频等内容。在应用程序中的某些点,我对应用程序预测用户很快将需要的内容进行批量下载。所有这些都是通过我自己的缓存系统和后台线程完成的。它的基本要点是,我向缓存发送 url,它会哈希为文件名,然后我们搜索该文件的正确位置,如果存在,我们返回找到的文件的位置,如果不存在,我们下载文件,然后返回文件的位置。当我执行批处理操作时,我将它们放入队列中,这样它们就不会堵塞线程池并导致无法完成其他更高优先级的异步任务。这样,由于队列在完成前一个任务后运行一个新的异步任务,如果设备无法运行多个任务,那么我现在需要完成的任务将是下一个任务。

这就是问题所在。

如果我当前正在将某个音频文件写入 SD 卡,如果我在队列运行时请求它,会发生什么?两个线程可以尝试同时写入同一个文件吗?

或者它会找到该文件,并返回一个半创建且损坏的文件吗?

我该如何避免这种情况?

我想过可能通过优先级队列运行所有内容,但是对于能够运行多个异步线程的设备,这将造成更严格的瓶颈。

编辑:

我的应用程序涵盖 Android 2.3-current

根据这个线程 Running multiple AsyncTasks at the same time -- not possible?

看起来,根据操作系统/设备版本,任务可能会并行运行(一次全部运行到一定限度)或一次运行一个。

xD 这就是为什么我尝试自己管理它们。

最佳答案

您可以使用 ConcurrentHashMap避免多线程写入同一个文件的问题。

ConcurrentHashMap<String, Boolean> map = new ConcurrentHashMap<>();

public void writeToFile(String fileName, byte[] data) {
    // putIfAbsent returns the value previously associated with fileName, or null
    if(map.putIfAbsent(fileName, Boolean.TRUE) == null) {
        try(FileOutputStream stream = new FileOutputStream(fileName)){
            stream.write(data);
        } finally {
            map.remove(filename);
        }
    }
}

只要所有线程都使用 putIfAbsent 防护,这将防止多个线程写入同一文件名。

关于java - 缓存和线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16322231/

相关文章:

java - 忽略依赖 jar 中的 log4j2.properties

.net - TraceSource.Trace 方法是否会阻塞调用线程,直到它被所有监听器处理为止?

android - ActionBar 覆盖 GridView 填充或自定义 GridView 以显示整个第一张图片?

android - 打开的文件太多错误 - 调试

java - 我可以在以前版本的 Android 操作系统上使用 Android N 平台开发的应用程序吗

java - 为什么 CyclicBarrier reset() 方法抛出 BrokenBarrierException

java CyclicBarrier 不会因重置而损坏

java - 寻找SVG绘图应用程序,基于Java的开源 batik 库

java nio NoFilepatternException如何处理文件路径中的空格

java - EJB : Two stateless objects use two different transaction