我在许多地方看到它说在迭代时从ArrayList中删除一个元素时,我应该使用iterator remove方法而不是collections remove方法来避免并发修改异常.
但是,下面的代码可以正常使用Java 1.8 Collection remove而不会给出并发修改异常.你可以看到我在这里没有使用迭代器来删除对象.
List<MyObject> list = new ArrayList<MyObject>();
list.add(new MyObject());
list.add(new MyObject());
list.add(new MyObject());
for (int i=0; i<list.size(); i++) {
list.remove(i);
}
Run Code Online (Sandbox Code Playgroud) 我的用例是我需要同时在一个表上执行GRANT和TRUNCATE语句。
示例场景:
当我尝试并行执行以下语句(两个单独的终端)时:
while true; do psql -U <user> -d <database> -c 'GRANT select ON test1 TO <user>;'; done
while true; do psql -U <user> -d <database> -c 'TRUNCATE test1;'; done
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
ERROR: tuple concurrently updated
Run Code Online (Sandbox Code Playgroud)
我不明白该错误的原因。该TRUNCATE语句与特权无关。那为什么不能同时执行这些语句?
好的。这是场景。我有一个用户填写的表单来创建一个 Match 对象。我使用 anIntentService将信息写入后台线程上的文件。如果在boolean中传递了“true”的intenta,则ScoreFile也写入了相应的 a 。GlobalMatch是一个单例对象这里是IntentService代码:
public class WriteMatchService extends IntentService {
private static final String EXTRA_SCORES_FILE = "scores_file";
public static final String REFRESH_MATCH_LIST_INTENT_FILTER = "refresh_match_list";
public static Intent getIntent(Context context, boolean writeScoresFile) {
Intent intent = new Intent(context.getApplicationContext(),
WriteMatchService.class);
intent.putExtra(EXTRA_SCORES_FILE, writeScoresFile);
return intent;
}
public WriteMatchService() {
super("WriteMatchService");
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
boolean writeScoresFile = false;
if (intent != null) {
if (intent.hasExtra(EXTRA_SCORES_FILE)) …Run Code Online (Sandbox Code Playgroud) 我有一个对象 SomeObject,它表示作为文档存储在 Couchbase 中的对象。SomeObject 有一个 cas 变量,用于包含 CAS 值。
我有这样的代码:
/* Get two identical objects from Couchbase, they'll have identical CAS value */
SomeObject someObjectA = getSomeObjectFromCouchbase(sameId);
SomeObject someObjectB = getSomeObjectFromCouchbase(sameId);
/* Make arbitrary modifications to the objects */
someObjectA.getListInObject().add(arbitraryValue1);
someObjectB.getListInObject().add(arbitraryValue2);
/* Convert SomeObject objects to JsonDocument objects, ensuring the CAS value is set */
JsonDocument jsonDocA = JsonDocument.create(someObjectA.getId(), JsonObject.fromJson(mapper.writeValueAsString(someObjectA)), someObjectA.getCas());
JsonDocument jsonDocB = JsonDocument.create(someObjectB.getId(), JsonObject.fromJson(mapper.writeValueAsString(someObjectB)), someObjectB.getCas());
/* Perform upserts on both JsonDocument objects; expectation is the second one should …Run Code Online (Sandbox Code Playgroud) 我理解它背后的概念,但认为使用 ConcurrentHashMap 而不是 HashMap 可以解决它。因为ConcurrentHashMap可以防止不同线程的并发读取和修改。
但我仍然看到了例外。
这是代码片段 -
示例文件.java
prepareInfo(RequestHelper.getSender(request), someVar, concurrentMap);
....
...
private void prepareInfo(final Sender sender, final SomeVar someVar, final ConcurrentHashMap<String,
Object> concurrentMap){
final Info info = RequestHelper.getInfo(someVar);
someVar.setInfo(info);
if(sender != null){
prepareProfileInfo(sender.getUserDetails(), info, concurrentMap);
mapDetailsWithMap(sender.getDetails(), concurrentMap);
if(sender.getSenderId() != null){
concurrentMap.put("sender_id", sender.getSenderId());
}
concurrentMap.putAll(sender.getAdditionalProperties());
}
}
Run Code Online (Sandbox Code Playgroud)
错误堆栈跟踪是 -
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1445)
at java.util.HashMap$EntryIterator.next(HashMap.java:1479)
at java.util.HashMap$EntryIterator.next(HashMap.java:1477)
at java.util.concurrent.ConcurrentHashMap.putAll(ConcurrentHashMap.java:1083)
at SampleFile.prepareAccountInfo(SampleFile.java:114)
Run Code Online (Sandbox Code Playgroud)
有几个问题我不太清楚——
java iteration collections concurrenthashmap concurrentmodification
如果我在单核 PC 上生成 2 个线程,它是否曾经访问过例如 anArrayList在同一时间所以它会抛出ConcurrentModificationException?
我的直觉告诉我,虽然有 2 个线程,但它们无法实现真正的并行性,因为只有一个内核,它可以做的主要是从一个线程跳转到另一个线程,但不执行诸如同时执行的指令arrayList.add(element)。
目前我的代码导致间歇性的ConcurrentModificationException错误,可能是因为我循环遍历HashMap的方式:
for (Map.Entry<String, Entity> entry : entities.entrySet()) {
String key = entry.getKey();
Entity item = entry.getValue();
if (item.isDestroyed()){
entities.remove(key);
ViewManager.getInstance().removeItem(key);
//INSTRUCT THE ENTITY TO PERFORM IT'S DESTROYED BEHAVIOR item.Destroyed()
} else {
item.update(1);
ConsoleItem ci = new ConsoleItemImpl(item.getIdentifier(), item.getLocation(), ColorStringConverter.getInstance().StringToColor(item.getSide()), item.getAngle(), item.getShape(), item.toString(), item.isDestroyed(), item.isDamaged());
ViewManager.getInstance().updateItem(ci);
}
item.update(1);
}
// updateInfo call
ViewManager.getInstance().updateInfo(summary());
}
Run Code Online (Sandbox Code Playgroud)
如何通过HashMap连续循环并避免出现ConcurrentModificationException错误?
我有一个HashMap,它的类型HashMap<String,HashMap<String,int>>现在我需要迭代这个HashMap并删除任何键值为0的内部HashMaps.
如果这样的删除使内部HashMap为空,则从外部HashMap中删除内部HashMap的相应键.我尝试迭代它,然后删除符合要求的元素,但这引发了我ConcurrentModificationException.
我尝试了以下代码:
synchronized(MyConstants.cliListUpdateList)
{
synchronized(MyConstants.cliList)
{
outerEntries = MyConstants.cliListUpdateList.entrySet();
outerIterator = outerEntries.iterator();
while(outerIterator.hasNext())
{
outerEnt = (Entry) outerIterator.next();
innerHashMap = (HashMap) outerEnt.getValue();
synchronized(innerHashMap)
{//synchronize innerhashmap
innerEntries = innerHashMap.entrySet();
innerIterator = innerEntries.iterator();
synchronized(innerIterator)
{
while(innerIterator.hasNext())
{
innerEnt = (Entry) innerIterator.next();
int k = Integer.parseInt((String)innerEnt.getValue());
if(k==0)
{
innerHashMap.remove(innerEnt.getKey());
if(innerHashMap.isEmpty())
{
MyConstants.cliListUpdateList.remove(outerEnt.getKey());
}
ArrayList ports = (ArrayList) MyConstants.cliList.get(outerEnt.getKey());
ports.remove((String)innerEnt.getKey());
if(ports.isEmpty())
{
MyConstants.cliList.remove(outerEnt.getKey());
}
}
else
{
k--;
innerHashMap.put(innerEnt.getKey(), k+"");
MyConstants.cliListUpdateList.put(outerEnt.getKey(), innerHashMap);
}
}
}
}//synchronize innerhashmap
}
System.out.println(MyConstants.cliListUpdateList …Run Code Online (Sandbox Code Playgroud) java collections multithreading exception concurrentmodification
你好.
我正在运行服务器并添加了一个迷你游戏.
每当游戏即将开始时......它首先调用onStart().现在我在这一行得到ConcurrentModificationException:
for(Player p : waiting) {
Run Code Online (Sandbox Code Playgroud)
这是方法:
public void onStart() {
trawler.players.clear();
for(Player p : waiting) {
if(!boat.playerInArea(p)) {
waiting.remove(p);
}
}
for(Player p : waiting) {
trawler.players.add(p);
}
trawler.start();
waiting.clear();
}
Run Code Online (Sandbox Code Playgroud)
如果你需要课程,这里是:
TrawlerWaitingRoom.java:
package server.model.minigames.trawler;
import server.model.players.Location;
import server.model.players.Player;
public class TrawlerWaitingRoom extends WaitingRoom {
private Trawler trawler;
//private Location boat = new Location(2668,2674,3165,3185);
private Location boat = new Location(2808, 2811,3415,3425);
public TrawlerWaitingRoom(Trawler trawler) {
super(1, 2);
this.trawler = trawler;
}
@Override
public boolean startGame() {
if(trawler.inProgress()) …Run Code Online (Sandbox Code Playgroud) 我有一个由多个线程操作的ArrayList,由于ArrayList未同步,因此无法正常工作.我按照教授的指示将列表切换为Vector.向量是同步的,但我有与同步相关的异常抛出.
为什么会发生这种情况,如何在代码中避免并发异常?我不想只是玩游戏直到有效,我想做最好的事情.谢谢!
例外:
Exception in thread "Thread-3" java.util.ConcurrentModificationException
at java.util.Vector$Itr.checkForComodification(Vector.java:1184)
at java.util.Vector$Itr.next(Vector.java:1137)
at BytePe4D$ReadInts.run(BytePe4D.java:64)
Run Code Online (Sandbox Code Playgroud)
码:
import java.io.*;
import java.util.Vector;
public class BytePe4D {
private Vector<Integer> numbers;
public static void main(String[] args) {
new BytePe4D();
}
public BytePe4D() {
// Create ArrayList and reset sum
numbers = new Vector<Integer>();
// Call addInts 8 times, with filenames integer1.dat through integer8.dat
for (int i = 1; i <= 8; i++) {
File file = new File("PE Data/integer" + i + ".dat");
ReadInts thread …Run Code Online (Sandbox Code Playgroud) java multithreading synchronization vector concurrentmodification