如何同步整数数组的单个元素?
如果我想锁定整个数组,我可以使用 synchronized
关键字,如下所示:
int arr[];
synchronized void inc(int a, int b){
arr[a]=arr[a]+b;
}
但是我可以只锁定项目 arr[a]
以便其他线程仍然可以读取/同时写入数组的其他项?
If I want to lock the whole array I can use the synchronized
keyword like this:
int arr[];
synchronized void inc(int a, int b){
arr[a]=arr[a]+b;
}
But can I lock just the item arr[a]
so that other threads can still read/write other items of the array at the same time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
也许更适合您的结构是
AtomicIntegerArray
Maybe more appropriate structure for you is
AtomicIntegerArray
不是现成的,但您可以创建一个与 int 数组大小相同的对象数组,并用不同的对象填充该数组。因此,当您想要锁定 int 数组中的特定元素时,您可以在相应的索引处锁定该对象:
锁定时:
Not out-of-the-box, but you can create an Object array that is the same size as your int array and populate the array with distinct Objects. So when you want to lock on a particular element in the int array, you lock on that Object at the corresponsible index:
When locking: do
不,数组元素是基元,您无法锁定它们。 (如果它们是对象,也没有帮助,因为锁定仅对可变对象有帮助。您想要锁定数组索引,而不是该索引处的内容)。
想到的唯一可能的构造是创建一个唯一引用数组索引的键并对其进行同步(或使用
Semaphore
),但这只有在其他线程以相同方式访问数组时才有帮助。我想说改变你的设计,摆脱 int 数组并使用一个数据结构,让你同步对其元素的访问(用
Collections.synchronizedList()List
) code>) 将是一个很好的起点。No, the array elements are primitives, and you can't lock on them. (It wouldn't help if they were objects, either, because locking only helps for mutable objects. You want to lock the array index, not the contents at that index).
The only possible construct that comes to mind is to create a key that uniquely references the array index and synchronize on that (or use a
Semaphore
), but that will only help if the other thread accesses the array in the same way.I'd say change your design, get rid of the int array and use a data structure that lets you synchronize the access to its elements (a
List
wrapped withCollections.synchronizedList()
) would be a good starting point.如果这确实是您的瓶颈,那么完全不同的结构可能更合适。如果您有 8 个核心,那么它们必须很忙,并花费大约 1/8 的时间添加数字才能看到严重的争用。如果执行此操作大约占您工作量的 1/8,您应该将系统设计为根本不锁定此操作。
假设您需要获取多个线程中大量值的总和。例如,计算一个数字在很长的列表中出现的次数。
您可以拥有一组同步计数器,并在每次更新时使用相当昂贵的锁。 (同步速度很快,但比添加慢得多)
或者您可以让所有线程保留自己的总计,并在最后总结。除了您没有使用任何锁之外,最终的总数是相同的!
If this really is a bottle neck for you, a completely differnet structure is likely to be more appropriate. If you have say 8 cores, then they have to be busy and spending around 1/8 of there time adding numbers to see serious contension. If performing this operations is about 1/8th of your work you should design your system not to lock this at all.
Say you need to get the total of lots of values in multiple threads. e.g. count the number of occurances a number is seen in a very long list.
You could have one synchronized array of counters with a realtively expensive lock on each update. (SYnchronized is fast but much, much slower than an add)
Or you could have all the threads keep their own totals which you sum up at the end. The final total is the same except you haven't used any locks!