gpt4 book ai didi

java - 使Java设置线程安全

转载 作者:行者123 更新时间:2023-11-29 09:28:05 25 4
gpt4 key购买 nike

我正在像这样更新 Volley 的 onResponse 回调中的一个集合:

@Override
public void onResponse(String response)
{
if (!response.equals(Properties.PRODUCT_NOT_FOUND) || !response.equals(Properties.USER_NOT_FOUND))
{
if (user.getFavoriteProducts().contains(product.getId()))
{
user.getFavoriteProducts().remove(product.getId());

} else {
user.getFavoriteProducts().add(product.getId());
}

mSharedPreferencesManager.insertUser(user);
}
}

当同时收到两个响应时,该集合被同时访问。我试图让这个设置线程安全,但我无法让它工作,这是我到目前为止尝试过的:

使用 SynchronizedSet:

user.setFavoriteProducts(Collections.synchronizedSet(new HashSet<Long>()));

使用 CopyOnWriteArraySet:

user.setFavoriteProducts(new CopyOnWriteArraySet<Long>());

同步回调中​​的代码:

private static final Object object = new Object();

@Override
public void onResponse(String response)
{
synchronized (object)
{
if (!response.equals(Properties.PRODUCT_NOT_FOUND) || !response.equals(Properties.USER_NOT_FOUND))
{
if (user.getFavoriteProducts().contains(product.getId()))
{
user.getFavoriteProducts().remove(product.getId());

} else {
user.getFavoriteProducts().add(product.getId());
}

mSharedPreferencesManager.insertUser(user);
}
}
}

这些都不起作用,我们将不胜感激!

编辑:不起作用的是只插入了一个项目。


编辑 2:我尝试了 N0un 的方法,但仍然只插入了一项

这是我用过的代码:

@Override
public void onResponse(final String response)
{
Log.d(Properties.TAG, "[REST_CLIENT] Response received: " + response);

AsyncTask.execute(new Runnable()
{
@Override
public void run()
{
synchronized (RestClient.class)
{
if (!response.equals(Properties.PRODUCT_NOT_FOUND) || !response.equals(Properties.USER_NOT_FOUND))
{
if (user.getFavoriteProducts().contains(product.getId()))
{
Log.d(Properties.TAG, "[REST_CLIENT] Removing product from favorites: " + product.getId());
user.getFavoriteProducts().remove(product.getId());

} else {
Log.d(Properties.TAG, "[REST_CLIENT] Adding product to favorites: " + product.getId());
user.getFavoriteProducts().add(product.getId());
}

Log.d(Properties.TAG, "[REST_CLIENT] Updating user");
mSharedPreferencesManager.insertUser(user);

Log.d(Properties.TAG, "[REST_CLIENT] Set size: " + user.getFavoriteProducts().size());
}
}
}
});
}

这些是我得到的日志:

D/CUOKA: [REST_CLIENT] Response received: ACCEPTED
D/CUOKA: [REST_CLIENT] Adding product to favorites: 3921
D/CUOKA: [REST_CLIENT] Updating user
D/CUOKA: [REST_CLIENT] Response received: ACCEPTED
D/CUOKA: [REST_CLIENT] Set size: 1
D/CUOKA: [REST_CLIENT] Adding product to favorites: 2361
D/CUOKA: [REST_CLIENT] Updating user
D/CUOKA: [REST_CLIENT] Set size: 1

编辑 3:这是将用户插入 SharedPreferences 的代码:

public synchronized boolean insertUser(final User user)
{
mEditor = mSharedPreferences.edit();

Gson gson = new Gson();
String json = gson.toJson(user);

mEditor.putString(KEY_USER, json);

return mEditor.commit();
}

最佳答案

好吧,Volley 的监听器是在 UI 线程中使用经典的 Java Executor 调用的。我认为有一种机制可以在 UI 线程中有太多工作时取消一些监听器调用。

试试看:

@Override
public void onResponse(String response)
{
AsyncTask.execute(new Runnable() {

@Override
public void run()
{
synchronized (MyClassName.class) {
if (!response.equals(Properties.PRODUCT_NOT_FOUND)
|| !response.equals(Properties.USER_NOT_FOUND)) {
if (user.getFavoriteProducts().contains(product.getId())) {
user.getFavoriteProducts().remove(product.getId());

} else {
user.getFavoriteProducts().add(product.getId());
}

mSharedPreferencesManager.insertUser(user);
}
}
}
});
}

还可以查看这些回复:herehere以获得更多解释。

Simply move that data processing that is performed inside your listeners to a background thread / AsyncTask to free your UI thread and prevent the blocking.

编辑: 经过一些讨论和代码审查,我发现了(第二个)问题:user 在请求之前被检索,线程安全问题就在这里。在处理新请求时,用户 的数据尚未保存。因此,第二个请求在与第一个请求相同的 Set 上工作,而不是在新更新的 Set 中。所以 user 应该在我建议的 synchronized block 中检索,然后再进行其他处理。

关于java - 使Java设置线程安全,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41207959/

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