2012-09-17 21 views
0

我的Android应用程序中有三个服务被两个广播接收器触发。前两个写入文件并由一个广播接收器触发,因此我可以确保它们一个接一个执行(通过Context.sendOrderedBroadcast())。第三个是独立的,由一个单独的广播接收器触发,但是从前一个写入的同一个文件中读取。并发Android服务之间的资源共享或文件锁定

由于广播接收器可能会在同一时间或几乎同时被触发,因此该文件也可能被同时访问。我怎样才能防止这种情况发生?我希望能够先读取然后写入或写入然后读取。我只是不确定这个问题是否与Java并发性相似,因为如果我没有弄错,android服务是完全不同的野兽。

回答

0

首先,我不应该在Service s的主UI线程中完成文件I/O。它应该在另一个线程中完成,例如AsyncTask

其次,ReentrantLock方法更容易。锁定时,它会通知其他线程访问相同的资源以等待,并且只有在释放锁定时才继续。只需实例化一个new ReentrantLock()并在读取或写入文件的方法中共享该锁。只要您需要,就可以在ReentrantLock上调用lock()unlock()

0

一个解决方案是让您的写作任务在访问共享文件之前创建一个空的临时文件(如.lock),并在完成后删除相同的临时文件。

您的阅读任务可以检查.lock文件是否存在。您也可以使用FileLock

+0

我不太确定这两者中的哪一个都是很好的解决方案。 1)'.lock'文件的创建可能需要比服务本身已经能够访问文件更多的时间。 2)我只是试过了,显然它不会工作:http://stackoverflow.com/questions/12616975/how-to-start-concurrent-threads-that-acquire-a-file-lock-and-等待彼此 –

+0

@mattquiros感谢您的反馈意见 - 如果您找到了更好的方法,请随时添加您自己的答案(并接受它)。 – assylias

+0

不幸的是,我还没有,虽然我被告知要看'ReentrantLock'。类似于您的建议但可与其他线程重复使用的内容。 –

0

http://developer.android.com/reference/android/app/Service.html 请注意,与其他应用程序对象一样,服务在其宿主进程的主线程中运行。这意味着,如果你的服务要做任何CPU密集型(如MP3播放)或阻塞(如网络)操作,它应该产生自己的线程来完成这项工作。

我建议在单独的线程中读取/写入文件。您可以在同一个线程中使用Only one thread at a time!

+1

如果我在服务中产生一个单独的线程来执行这些任务(实际上,我在考虑更多的是'AsyncTask'),那么我是否会失去对前两个服务的背靠背执行的控制,即使我用'sendOrderedBroadcast()'?也就是说,因为这两个服务在它们内部有不同的线程,所以我将无法一个接一个地执行这两个服务。 –