开发者

How to synchronize single element of integer array?

开发者 https://www.devze.com 2023-04-12 13:20 出处:网络
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){

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?


Maybe more appropriate structure for you is AtomicIntegerArray


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
}


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.


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!

0

精彩评论

暂无评论...
验证码 换一张
取 消