0

私は長い間問題を解決するために多くの方法を検索しましたが、方法も私の問題を解決することができないので、この問題を解決するためにあなたの助けが必要です、どうもありがとうございました!

例外スタック:

java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextEntry(HashMap.java:977)
at java.util.HashMap$KeyIterator.next(HashMap.java:1012)
at org.bson.BSONEncoder.putIterable(BSONEncoder.java:258)
at org.bson.BSONEncoder._putObjectField(BSONEncoder.java:198)
at org.bson.BSONEncoder.putObject(BSONEncoder.java:140)
at org.bson.BSONEncoder._putObjectField(BSONEncoder.java:190)
at org.bson.BSONEncoder.putIterable(BSONEncoder.java:259)
at org.bson.BSONEncoder._putObjectField(BSONEncoder.java:198)
at org.bson.BSONEncoder.putObject(BSONEncoder.java:140)
at org.bson.BSONEncoder._putObjectField(BSONEncoder.java:190)
at org.bson.BSONEncoder.putObject(BSONEncoder.java:140)
at org.bson.BSONEncoder.putObject(BSONEncoder.java:86)
at com.mongodb.OutMessage.putObject(OutMessage.java:190)
at com.mongodb.DBApiLayer$MyCollection.update(DBApiLayer.java:341)
at com.mongodb.DBCollection.update(DBCollection.java:150)
at com.autonavi.sns.util.TileCache.updateToMongo(TileCache.java:589)
at com.autonavi.sns.util.TileCache.updatePoint(TileCache.java:349)
at com.autonavi.sns.workflow.function.UpdatePointFunc.updatePoint(UpdatePointFunc.java:82)
at com.autonavi.sns.workflow.function.UpdatePointFunc.doExec(UpdatePointFunc.java:37)
at com.autonavi.sns.workflow.function.SNSFunction.execFunc(SNSFunction.java:42)
at com.autonavi.sns.workflow.function.SNSFunction.execFunc(SNSFunction.java:45)
at com.autonavi.sns.workflow.function.SNSFunction.execFunc(SNSFunction.java:45)
at com.autonavi.sns.workflow.function.SNSFunction.execFunc(SNSFunction.java:45)
at com.autonavi.sns.workflow.function.SNSFunction.execFunc(SNSFunction.java:45)
at com.autonavi.sns.workflow.SNSWorkFlow.startExec(SNSWorkFlow.java:45)
at com.autonavi.sns.workflow.SNSWorkFlow.execute(SNSWorkFlow.java:31)
at com.autonavi.sns.service.SNSThreadHandler.serviceDispacth(SNSThreadHandler.java:79)
at com.autonavi.sns.service.SNSThreadHandler.run(SNSThreadHandler.java:47)
at java.lang.Thread.run(Thread.java:662)

更新キーを設定:

BasicDBObject udbo = new BasicDBObject();
udbo.put(ConstantUtil.MONGO_ID_KEY, tileId);

List<BasicDBObject> plist = new ArrayList<BasicDBObject>();
for (PointBasic p : points) {
    BasicDBObject pkey = new BasicDBObject();
    boolean isPhysic = p.isPhysicPoint();
    pkey.put("isphysic", isPhysic);
    pkey.put("x", p.getX());
    pkey.put("y", p.getY());
    pkey.put("picurl", p.getPicUrl());
    pkey.put("area", p.getArea());
    plist.add(pkey);
}

BasicDBObject pdbo = new BasicDBObject();
pdbo.put("$set", new BasicDBObject("point", plist));

return this.updateToMongo(udbo, pdbo, TILE_LAYER);

キーを mongo に更新します。

private boolean updateToMongo(BasicDBObject udbo, BasicDBObject ukey, long layer) {
    boolean flag = false;
    try {
        this.mongo = MongoDatabaseUtil.getInstance();
        this.coll = mongo.getCollection(ConstantUtil.TILE_COLL + layer);
        this.coll.update(udbo, ukey, true, true);
        flag = true;
    } catch (MongoException e) {
        LOG.error("Mongo error : ", e);
    }

    return flag;
}
4

2 に答える 2

1

確認するのに十分な情報はありませんが、アプリケーションがマルチスレッドであり、現在のスレッドがを呼び出している間に他のスレッドが更新していると思われます。BasicDBObjectupdateToMongo

これに対する魔法の解決策はありません。永続化している間、他のスレッドがメモリ内コピーを更新するのを停止する必要があります。


はい、私のアプリケーションはマルチスレッドですが、新しいクラスでupdateToMongoを呼び出すすべてのスレッドは、BasicDBObjectがupdateToMongoメソッドに影響しますか?

updateToMongo呼び出しが別のクラスまたは別のインスタンスで「発生」することは適切ではないと思います。BasicDBObject別のスレッドが同じインスタンスを永続化しようとしているときに、あるスレッドが特定のインスタンスを更新しているため、問題が発生しています(私は推測しています) 。(理論的には、これを実行しているのと同じスレッドである可能性もあります...しかし、そのシナリオは少し遠いです。)

于 2012-02-22T02:42:59.837 に答える
0

for-each ループを使用して、「ポイント」コレクションを反復処理しています。アプリケーションがマルチスレッドで、'points' コレクションを変更 (追加、削除など) すると、このエラーが発生します。

いくつかのオプションがあります。まず、通常の for ループを使用して、現在のインデックスでオブジェクトを取得します。

for (int i = 0; i < points.size(); i++) {
   PointBasic p = points.get(i); // could be different depending upon your collection type.
   ...
}

ただし、反復中にポイント コレクションを変更すると、一部のデータがスキップされる可能性があり、それについてはわかりません:O
この操作が必須の場合は、コードを同期してみてください。
(コードを同期すると、同じブロックにラップされたコードがスレッド間で同時に実行されることはありません。)

<global>
private Object pointsLock = new Object();
</global>

synchronized (pointsLock) {
   for (PointBasic p : points) {
      BasicDBObject pkey = new BasicDBObject();
      boolean isPhysic = p.isPhysicPoint();
      pkey.put("isphysic", isPhysic);
      pkey.put("x", p.getX());
      pkey.put("y", p.getY());
      pkey.put("picurl", p.getPicUrl());
      pkey.put("area", p.getArea());
      plist.add(pkey);
   }
}

「ポイント」非同期を変更するすべてのコードを同じ同期ブロックにラップします。また、必ず同じロック オブジェクトを使用して同期してください。

Iterator (まったくお勧めしません) または while ループを使用することもできますが、最終的には for ループとほぼ同じことを行い、おそらく効率が低下します。

与えられたスタック トレースには正確に従っていませんでしたが、ポイントの更新について何かを述べているので、まったく関係のない資料を投稿しないことを願っています。:)

于 2012-02-22T03:42:44.000 に答える