tl; dr:
我有两个线程,其中一个线程实现对象,另一个试图读取对象。如何避免冲突,即同步文件访问?
更多信息:
我有使用AsyncTask来获取数据,然后序列化对象的服务:
@Override
protected Boolean doInBackground(Void... params) {
FeedItem currentItem = mParser.parseFeed();
Util.saveItem(UpdateService.this, currentItem);
}
对象序列化:
public class Util {
private static final String sFileName = "feedobject";
public static FeedItem loadItem(Context context) {
FeedItem result = null;
try {
FileInputStream fis = context.openFileInput(sFileName);
ObjectInputStream is = new ObjectInputStream(fis);
result = (FeedItem) is.readObject();
is.close();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return result;
}
public static void saveItem(Context context, FeedItem item) {
FileOutputStream fos;
try {
fos = context.openFileOutput(sFileName, Context.MODE_PRIVATE);
ObjectOutputStream os = new ObjectOutputStream(fos);
os.writeObject(item);
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
我也尝试从Activity(即UI线程)中读取对象。
mTextView.setText(Html.fromHtml(Util.loadItem(this).message));
最佳答案
如果可以在Android下重命名文件,则可以将对象写入临时文件"feedobject.t"
,然后将其重命名为"feedobject"
,该原子应该是原子的。
private static final String sFileName = "feedobject";
private static final String tempFileName = "feedobject.t";
...
File tempFile = new File(tempFileName);
... // write the file
tempFile.renameTo(new File(sFileName));
如果这不起作用,那么您将被迫拥有同步锁。消费者应锁定并等待生产者完成写入。生产者需要锁定以确保仅在消费者未阅读时才在写。
您只需使
saveItem
和loadItem
方法同步即可锁定该类:public static synchronized FeedItem loadItem(Context context) {
...
public static synchronized void saveItem(Context context, FeedItem item) {
...
最好是创建一个锁定对象并对其进行锁定:
private static final Object itemLock = new Object();
然后在
loadItem
和saveItem
方法中锁定该对象:public static FeedItem loadItem(Context context) {
synchronized (itemLock) {
// do the reading...
}
希望这可以帮助。