onkami
onkami

Reputation: 9411

Non-locking interaction with an array from several threads (in Java)

I would need an array of Strings to be accessed from two threads. It has to be very fast and thread-safe. I prefer not to use locks, what approach I can take to make lock-free thread-safe array of Strings? I need a recipe in Java.

Upvotes: 2

Views: 252

Answers (2)

Alejandro C.
Alejandro C.

Reputation: 3801

How about using the built in Collections.synchronizedList?

Upvotes: 0

Chill
Chill

Reputation: 1113

By definition, the only thread-safe writes available to memory shared by contended threads are actions that are provided by atomic instructions in the CPU. This isn't really relevant for Java (at least, almost all of the time), but it is worth noting that writes without locks in a concurrent environment are possible.

So, this is to say, that if you want to write to the array, you are likely going to need to have locks. Locks are the solution to the general problem.

You can, however, happily share an array between many threads without issue as long as they are only reading from the array. So, if your array is immutable (or any other object for that matter), it will be thread-safe by virtue of there never being an opportunity for contention.

So, let's suppose you want to write to the array from two different threads, but you are worried about contention. Maybe each thread wants to be recording a lot of data. There's several different solutions to this problem: I'll try to explain a few. This isn't exhaustive because concurrency is a hard problem to solve and although there are some common approaches, often enough the answer really depends on the specific situation.

  1. The simplest approach

Just use a lock on the array when you write to it and see how it performs. Maybe you don't actually need to worry about performance problems right now.

  1. Use a producer/consumer approach

Rather than having two threads write to the same array, have each of them "produce" values (maybe put them on different thread-safe queues) and have another thread responsible for "consuming" those values (remove them from the queue and put them in the array).

If order matters, this approach can be tricky to implement. But you are using concurrency, so ordering will be fairly non-deterministic anyways.

  1. Do writes in batches

The idea here is that you would store the values you want to put in the array from each thread in it's own temporary batch of values. When the batch reaches a large enough size, the thread would lock the array and write the entire batch.

  1. Write to separate parts of the array

If you know the size of your data, you can avoid contention by simply not allowing threads to write to the same index ranges. You'd divide the array up by the number of threads. Each thread, when created, would be given a start index into the array.

This option might fit what you are looking for (lock-free, thread-safe).

Upvotes: 2

Related Questions