我正在编写一个应用程序来模拟书籍市场。
考虑一本名为“ BookA”的书,它具有以下数据:
45 47 50 51 55 70 73 75 79 81
**Bookstore1 Buy Qty** 2 3 5 11 1
**Bookstore2 Buy Qty** 1 3 5 1 10
**Bookstore1 Sell Qty** 1 11 7 8 20
**Bookstore2 Sell Qty** 2 5 2 5 10
**Data for BookA**
数值数据存储为
volatile int[][] dataStorage = new int[5][10]
,其中行[0]包含价格。row [1] ..row [4]包含每个书店可用的数量。
例如,row [1] col [0]表示Bookstore1愿意以$ 45的价格购买2份BookA。类似地,row [4] [5]表示Bookstore2愿意以$ 70的价格出售2份。
我的市场上大约有500本书,每本书的数据都存储在ConcurrentHashMap中:
(
ConcurrentMap<String, int[][]> map = new ConcurrentHashMap<String, int[][]>(500)
)“ BookA” ----> int [] []
“ Bookn” ----> int [] []
Bookstore1和Bokstore2中的数据通过两个单独的线程到达。目前,我将原始数据对象存储在阻塞队列中,并使用单个线程(“ ProcessingThread”)创建和修改(如果有更新)上述数组。
最后,我有一些客户,他们在一个单独的线程(“ CustomerThread”)中向我发送定单以购买/出售书籍。
一个典型的订单如下:“以50美元购买BookA 3”:
获得订单后,我将执行以下操作:
1)检查地图是否包含键“ BookA”。
2)如果是,那么我在按住ReadLock(ReentrantReadWriteLock.ReadLock)的同时为BookA克隆数据(int [] [])。
3)然后,我对克隆的数据进行迭代以找到价格和总数量。
我的问题是:
a)有人可以确认我不需要同步生产者(“ ProcessingThread”)。由于dataStorage(int [] [])仅由“ ProcessingThread”线程更改。此外,由于dataStorage是易失性的,因此在我对其进行写入时将建立“ happens-before”(因此,“ CustomerThread”将看到最新的更新数据)。
b)是否有更好的方法(比使用锁更具可伸缩性)来确保“ CustomerThread”中的线程安全?我可以使用AtomicIntegerArray逃脱吗?
谢谢
最佳答案
我在这里有点麻烦。您的数组是易失的,但元素不是。仅需一个线程即可修改元素,因此您很安全。但是您不能保证CustomerThread将看到元素更改。同样,即使元素本身是易失性的(不容易完成),该数组也会以少量和单调形式更改,并且CustomerThread倾向于查看不完整的数据。
第一个解决方案是对每个阵列进行适当的锁定。然后,CustomerThread必须等待,直到准备好完整的数组为止。 (使用多个CustomerThreads可以解决一本书阻止其他书籍执行操作的问题,但我认为这不会使您的并发问题更加严重。)
另一个解决方案是替换整个数组,而不是修改它们。数组实际上变得不可变。从一组数据到下一组数据的更改是瞬时的,并且数据始终是一致的。现在,数组引用是易失性的事实确保了更改将立即对CustomerThread可见,而CustomerThread现在不必等待锁定。
我喜欢第二种解决方案,它回答了您的问题B。(原子往往很昂贵。如果您可以用一个原子替换一个锁,那您将领先于游戏,但是如果您要用100替换一个锁,原子,甚至只有10个,您就落后了。)
但是,我有点担心要收到多个订单。如果还剩一本书,您不想将其卖给5个不同的人。在我看来,根据您所写的内容,需要仔细同步CustomerThread上的订单和从阻塞队列进入ProcessingThread的信息。 ProcessingThread和CustomerThread都是一个线程,因此它们可以单独使用。但是他们可以同时做一些事情,例如删除可用的书籍数量并订购一些书籍。这两个事件需要顺序发生,所以我们知道谁拿到了书,而正式的Java同步块使我震惊,这是最好的方法。
但是您最清楚您要做什么(我对书店将哪些数据放入队列感到有些困惑)。希望这可以给您一些信息,如果它实际上不能回答您的问题。
关于java - 读取阵列锁定,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/11941307/