线程安全 - 后台线程和缓存=>避免竞争条件

时间:2014-11-01 19:24:01

标签: android multithreading thread-safety

我想保持我的后台线程和我的观点完全分离,因此我使用线程和总线系统(实际上我使用的是一个职业经理,来自这里:https://github.com/path/android-priority-jobqueue)。为了获得更好的用户体验,我将已计算或加载的数据缓存在LruCache中。我已经编写了一个包装器来保证线程安全。必须在后台完成的每项工作都由标签识别。

我在自己的单例类中跟踪工作线程。

我的主题如下:

  • 将作品的标签放入单件类=>的列表中意思,工作将完成
  • 做好工作
  • 将结果保存在缓存中
  • 将活动发布到巴士
  • 从单件类列表中删除标签=>意思,工作已经完成

当片段恢复时,我会使用以下系统:

  • 在巴士上注册
  • 检查缓存中是否存在现有结果
  • 使用缓存数据或通过检查单例类列表中的标记来检查线程是否正在计算所需数据
  • 如果某个线程正在处理所需的数据,请等待它,否则,启动一个新线程

我认为,这很容易出现一种竞争条件:

  • 线程完成并将结果发布到总线
  • =>片段尚未注册,因为它没有恢复
  • =>活动不会发送,只会缓存
  • =>片段得到了恢复
  • => fragment询问工作状态,看到一个线程正在处理所需数据并且没有启动新线程
  • =>线程清除所需数据的工作状态

=>片段不会收到它的数据

我该如何解决这个问题?如果我考虑两个独立的线程,这种竞争条件是可能的。在andoroid上,线程将在主线程上发布ALWAYS,这会影响我的问题吗?我实际上并不确定......

这是我的主要线程otto总线的完整性:

// defined in my application
private static final MainThreadBus BUS = new MainThreadBus(new Bus(ThreadEnforcer.ANY));

// the bus class
public class MainThreadBus extends Bus
{
private final Bus mBus;
private final Handler mHandler = new Handler(Looper.getMainLooper());

public MainThreadBus(final Bus bus)
{
    if (bus == null)
        throw new NullPointerException("ERROR: bus == null");
    mBus = bus;
}

@Override
public void register(Object obj)
{
    mBus.register(obj);
}

@Override
public void unregister(Object obj)
{
    mBus.unregister(obj);
}

@Override
public void post(final Object event)
{
    if (Looper.myLooper() == Looper.getMainLooper())
    {
        mBus.post(event);
    }
    else
    {
        mHandler.post(new Runnable()
        {
            @Override
            public void run()
            {
                mBus.post(event);
            }
        });
    }
}
}

0 个答案:

没有答案