gpt4 book ai didi

java - 两个线程之间的资源同步访问

转载 作者:太空宇宙 更新时间:2023-11-04 10:50:51 24 4
gpt4 key购买 nike

我有两个线程和一个缓存。我们将线程 1 称为 Tb,它是后台线程(即具有较低优先级),另一个线程称为 Tm(具有较高优先级的主线程)。有一个缓存由两个线程更新。您可以说线程 Tb 是 Tm 的助手,用于在可能的情况下抢占式填充缓存。

问题是,当 Tm 想要访问缓存时,它必须立即访问它,因为某些 UI 更新显示依赖于它。

由于缓存是为并发写入而共享的,因此我对缓存的访问进行了同步,如下所示:

Element checkAndUpdateCache(int elementPositionToBeChecked){

Element toBeReturned;

synchronized(lock){

// Check if the element is already present in the cache
if(!cache.hasElement(elementPositionToBeChecked)){

// If not, retrieve a new one and fill the cache
toBeReturned = retrieveNewElement(elementPositionToBeChecked);
cache.put(elementPositionToBeChecked, toBeReturned );
}
else{
toBeReturned = cache.getElement(elementPositionToBeChecked);
}

}

return toBeReturned;

}

问题在于,由于后台线程在循环中调用此方法,因此它需要非常快速地持续访问缓存,并且几乎永远不会释放锁。目前,我在每个循环周期后调用 Thread.yield(),另外调用 Thread.sleep(10) 以提供对主线程的一些访问权限。

拥有不同的优先级并没有真正的帮助,在每个循环周期调用 Thread.yield() 也没有帮助。 Thread.sleep() 确实有所帮助,但我认为,我们都同意,这根本不是一个好的策略。毕竟,我们想要最大的 CPU 利用率,对吗?

是否有某种方法可以确保每当主线程需要访问缓存时,它都能在后台线程等待时轻松获取并稍后恢复操作?

编辑:实现细节

缓存是 Map<Integer, Album>对于 key 为 Integer 的情况.

public static Album getAlbum(Context context, int position, @NonNull Cursor cursor, @NonNull Map<Integer, Album> cache){

// Do we have the Album in cache
Album albumInfo = cache.get(position);

if(albumInfo == null){

cursor.moveToPosition(position);

// Let's cache this Album
albumInfo = Album.fromMediaStoreCursor(context, cursor);
cache.put(position, albumInfo);
}
EDIT 2
return albumInfo;
}

编辑2:正在限制的后台线程循环

// While we pre-emptively fetch the Albums to cache in the background :)
if (cursorImages != null) {

for (int i = 0; i < cursorImages.getCount(); i++) {

synchronized(SnapsboardApplication.getInstance()) {
AlbumsListCursorAdapter.getAlbum(ListPhotoVideoAlbumsOnDeviceActivity.this,
i, cursorImages, cache);
}

// Keep checking if we have been asked to cancel
if (isCancelled()) {
return null;
}

try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
Thread.yield();
}
}

最佳答案

在不了解完整实现的情况下,很难给出真正好的建议,但我想到的一个可能的解决方案是将 map 的定义更改为 Map<Integer, Future<Album>>并使用 ExecuterService检索要添加到 map 的数据。这样,后台线程就不应该在方法内停留太久 retrieveNewElement(elementPositionToBeChecked) (我认为这是主线程阻塞的原因)并且即使检索尚未完成,主线程也已经得到结果。调用future.get(timeout, TimeUnit.SECONDS)将返回所需的值或将阻塞直到检索完成(或达到超时)。

关于java - 两个线程之间的资源同步访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47881352/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com