如何允许从同步结构中同时读取?

时间:2018-09-03 11:33:53

标签: java concurrency synchronized

假设我有一个像这样的简单缓存实现:

class ViewModel : BaseViewModel{
    private Grid _userGrid { get; set; }
    public Grid UserGrid
    {
        get { return _userGrid; }
        set        
        {
            _userGrid = value;
            OnPropertyChanged();

        }
    }
    public override async Task InitAsync()
    {
        await Task.Factory.StartNew(() =>
        {
            _userGrid = new Grid
            {
                ColumnSpacing = 1,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand
            };
            _userGrid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(GridHeightSize * 4) });
// and adding some content to This grid
         }
     }

我需要防止:

  1. 同时写入class Cache<Item> { private InternalStorage internalStorage; public synchronized Collection<Item> find(String query) { // find Items from internalStorage } public synchronized void add(Collection<Item> items) { // Add items to internalStorage } } 。即没有同时调用internalStorage
  2. 与写入同时发生的读取。即无法同时呼叫addfind

上面的实现满足了这些安全要求,但是,同时调用add不会造成任何损害,因为它不会更改数据。在保持结构线程安全的同时,我该如何允许呢?

2 个答案:

答案 0 :(得分:3)

如果您在此处使用ReentrantReadWriteLock而不是synchronized,这似乎很容易做到。

答案 1 :(得分:0)

展开Eugene's answer。这是应用ReentrantReadWriteLock来实现我所需要的方法:

class Cache<Item> {
    final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();

    private Map<String, Item> internalStorage;

    public Collection<Item> find(String query) {
        rwl.readLock().lock();
        try {
            // find Items from internalStorage
            // ...
            return result;
        } finally {
            rwl.readLock().unlock();
        }
    }

    public void add(Collection<Item> items) {
        rwl.writeLock().lock();
        try {
            // Add items to internalStorage
            // ...
        } finally {
            rwl.writeLock().unlock();
        }
    }
}