John Hinnegan
John Hinnegan

Reputation: 5962

Java concurrency - writing to different indexes of the same array

Suppose I have an array of data, can 2 threads safely write to different indexes of the same array concurrently? I'm concerned about write speed, and I want to synchronize the 'get index to write at' bit vs the actual writing.

I am writing code that lets me assume 2 threads will not get the same index.

Upvotes: 36

Views: 6702

Answers (4)

aioobe
aioobe

Reputation: 421160

For two different indexes in an array the same rules apply as for two separate variables.

The Chapter "Threads and Locks" in the Java Language Specification starts by stating:

17.4.1 Shared Variables

[...]

All instance fields, static fields and array elements are stored in heap memory. In this chapter, we use the term variable to refer to both fields and array elements.

This means that you can safely write to two different indexes concurrently. However you need to synchronize a write/read to the same index if you want to make sure the consumer thread sees the last value written by the producer thread.

Upvotes: 41

chubbsondubs
chubbsondubs

Reputation: 38865

Well yes it's technically true, but there are so many caveats to this answer it makes me feel very worried to tell you yes. Because while you can write to two different locations in an array you can't do much else without running into concurrency issues. The real question comes in what next are you going to do if you could do this?

If you had counter variables that moved as arrays wrote to different locations, you could run into concurrency issues. It's possible that as your array fills up you could have two threads try and write to the same location. If you potentially had a reader of the array that could read the same location that's being written too you'll have concurrency issues. Besides writing doesn't do anything if you never plan on reading it back therefore, I think you'd have concurrency problems when you go to add the reader (which will have to lock your writers out). Then there's the question of if you don't move where the threads write to what keeps it from writing over the data? And if you don't ever move the head of where the thread writes to why are you using an array? Just given them individual Latches or variables of their own to write to, and really keep them separated.

Without a full picture of your intentions saying "yes" might lead you into peril without thinking about why you are doing what you are doing.

Upvotes: 1

Ravi Bhatt
Ravi Bhatt

Reputation: 3163

Have a look at CopyOnWriteArrayList, provided you are okay with an arrayList. from its documentation,

A thread-safe variant of ArrayList in which all mutative operations (add, set, and so on) are implemented by making a fresh copy of the underlying array.

This is ordinarily too costly, but may be more efficient than alternatives when traversal operations vastly outnumber mutations, and is useful when you cannot or don't want to synchronize traversals, yet need to preclude interference among concurrent threads.

And

An instance of CopyOnWriteArrayList behaves as a List implementation that allows multiple concurrent reads, and for reads to occur concurrently with a write. The way it does this is to make a brand new copy of the list every time it is altered.

Reads do not block, and effectively pay only the cost of a volatile read; Writes do not block reads (or vice versa), but only one write can occur at once.

Upvotes: -1

Tomasz Nurkiewicz
Tomasz Nurkiewicz

Reputation: 340933

Modifying two different variables in two different threads is safe. Modifying two different elements in an array can be compared to modifying two different variables under different memory addresses, at least as far as OS is concerned. So yes, it is safe.

Upvotes: 12

Related Questions