java – 巨大数据模型中的线程安全性

背景:
我在内存中有一个(或多或少)巨大的数据模型.该模型包含大约3.150.000到12.600.000个可以直接修改的对象.此外,大约有75.000.000个对象只能通过3.150.000到12.600.000对象进行修改.

另一方面,大约有10个模块访问模型.这些模块可以分为:

>每250毫秒到1000毫秒读取和修改一些对象
>按需阅读和修改一些对象
>如果已经更改了某些对象,请将其读取

题:
如何同步这样的数据模型?我脑子里有以下想法:

(1)锁定每个可以直接修改的类.
优点:只能锁定已修改的对象.
缺点:高同步工作量和大量锁定实例(3.150.000到12.600.000附加对象/锁).在同步(死锁等)中做错事的风险很大.

(2)访问整个数据模型的*界面.此接口将通过单个锁定锁定整个模型的每个修改.
优点:只有一个锁 – >减少同步工作量.
缺点:无论更改类型如何,整个模型都会被锁定.

(3)调度线程(如在AWT / Swing中).处理任务(事件)的线程.
优点/缺点如想法(2).但是,这将是一个基于事件的解决方案.我阅读了Graham Hamilton关于GUI-tollkits中多线程的文章.此外,John Ousterhout还谈到了“事件与线程”.当然,我的数据模型并不广泛,但文章深入到了问题的核心.

这里链接到Graham Hamilton的文章:https://weblogs.java.net/blog/kgh/archive/2004/10/multithreaded_t.html

那么,你的经历是什么?也许你有一个更好的主意.

编辑:我在对象计算上犯了一个大错误.我刚刚更新了金额.

提前致谢 :)

编辑2:这是我刚刚为演示目的创建的模型:

enum Ware { WOOD, COAL, STONE }
class Stock { Map<Ware, Integer> internalStock; }
class Coordinate { int x; int y; }
interface ILand {}

class World {
  Map<Coordinate, ILand> land;
  Map<Coordinate, Ship> ships;
}

class Island implements ILand { Stock resources; }
class Ship { Stock stock; }
class Building {Stock stock; }

class Colony implements ILand {
  Island builtOn;
  Set<Building> building;
}

class Character {
  Set<Colony> colonies;
  Set<Ship> fleet;
}

这将是数据模型的结构:

Model
   World     <>--- ILand
             <>--- Ship
   Character <>--- Colony <>--- Building <>--- Stock
                          <>--- Island   <>---Stock
             <>--- Ship   <>--- Stock

解决方法:

您可能需要考虑将数据模型转换为不可变的持久数据结构.

这种方法在Scala和Clojure等语言中非常有效.如果您想更好地理解这种技术,以下视频非常值得关注:

http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey

当您具有重要的并发访问权限时,这通常是一个很好的策略:它具有各种优势:

>读者不需要任何锁定.在有许多读者的情况下,这可以获得巨大的成功.
>更新可以原子方式发生 – 这意味着您永远不会冒着读者看到数据处于不一致状态的风险.
>您可以随时获取整个数据结构的“快照”.由于不可变数据结构无法更改,因此您可以*地获取对它的引用,然后在闲暇时进行检查
>更新仍然相对便宜:结构共享意味着您可以通过一些更改来创建数据模型的新版本,而无需复制整个数据模型.
>您可以拥有各种不同的更新语义,以满足您的要求.在这种情况下,听起来你有一个“读取和更新”语义与某种形式的变更通知相结合.

上一篇:javascript – NodeJS mysql同步查询


下一篇:关于Java中的同步方法