如何同步整数数组的单个元素?

发布于 2024-12-09 08:49:38 字数 221 浏览 0 评论 0原文

如果我想锁定整个数组,我可以使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

隔岸观火 2024-12-16 08:49:38

也许更适合您的结构是 AtomicIntegerArray

Maybe more appropriate structure for you is AtomicIntegerArray

清醇 2024-12-16 08:49:38

不是现成的,但您可以创建一个与 int 数组大小相同的对象数组,并用不同的对象填充该数组。因此,当您想要锁定 int 数组中的特定元素时,您可以在相应的索引处锁定该对象:

final Object[] locks = new Object[arr.length]:
for(int i = 0; i < arr.length; i++) {
 locks[i] = new Object();
}

锁定时:

synchronized(locks[a]) {
  // do something here
}

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:

final Object[] locks = new Object[arr.length]:
for(int i = 0; i < arr.length; i++) {
 locks[i] = new Object();
}

When locking: do

synchronized(locks[a]) {
  // do something here
}
生活了然无味 2024-12-16 08:49:38

不,数组元素是基元,您无法锁定它们。 (如果它们是对象,也没有帮助,因为锁定仅对可变对象有帮助。您想要锁定数组索引,而不是该索引处的内容)。

想到的唯一可能的构造是创建一个唯一引用数组索引的键并对其进行同步(或使用 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 with Collections.synchronizedList()) would be a good starting point.

毁虫ゝ 2024-12-16 08:49:38

如果这确实是您的瓶颈,那么完全不同的结构可能更合适。如果您有 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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文