I have a class Helper with one single method int findBiggestNumber(int [] array) and no instance variables.
If I make an object Helper h = new Helper(); and let 10 different threads use that object's only method findBiggestNumber to find their array's biggest number, will they interfere with each other?
My fear is that for example thread-1 starts calculating its array's biggest number when the parameter in findBiggestNumber is referencing an array in for example thread-8. Could that happen in my example?
No the problem you described could not happen. As your Helper class has no members, it is thread safe.
Thread safety issues arise when mutable (changeable) data is shared between multiple threads. However in your example, Helper does not contain any data (i.e. variables) that will be shared between multiple threads as each thread will pass their own data (int[] array) into Helper's findBiggestNumber() method.
Without your implementation of findBiggestNumber, it's impossible to say if it is thread safe since you could be mutating the array passed as an argument. If that is true, and you pass the same array to multiple threads, then there is potentially a race condition; otherwise, it is thread safe.
findBiggestNumber could also be modifying global or static data which would also make it thread unsafe.
Related
The Javadoc in Guava's ImmutableList says that the class has the properties of Guava's ImmutableCollection, one of which is thread safety:
Thread safety. It is safe to access this collection concurrently from multiple threads.
But look at how the ImmutableList is built by its Builder - The Builder keeps all elements in a Object[] (that's okay since no one said that the builder was thread safe) and upon construction passes that array (or possibly a copy) to the constructor of RegularImmutableList:
public abstract class ImmutableList<E> extends ImmutableCollection<E>
implements List<E>, RandomAccess {
...
static <E> ImmutableList<E> asImmutableList(Object[] elements, int length) {
switch (length) {
case 0:
return of();
case 1:
return of((E) elements[0]);
default:
if (length < elements.length) {
elements = Arrays.copyOf(elements, length);
}
return new RegularImmutableList<E>(elements);
}
}
...
public static final class Builder<E> extends ImmutableCollection.Builder<E> {
Object[] contents;
...
public ImmutableList<E> build() { //Builder's build() method
forceCopy = true;
return asImmutableList(contents, size);
}
...
}
}
What does RegularImmutableList do with these elements? What you'd expect, simply initiates its internal array, which is then used for all read oprations:
class RegularImmutableList<E> extends ImmutableList<E> {
final transient Object[] array;
RegularImmutableList(Object[] array) {
this.array = array;
}
...
}
How is this be thread safe? What guarantees the happens-before relationship between the writes performed in the Builder and the reads from RegularImmutableList?
According to the Java memory model there is a happens-before relationship in only five cases (from the Javadoc for java.util.concurrent):
Each action in a thread happens-before every action in that thread that comes later in the program's order.
An unlock (synchronized block or method exit) of a monitor happens-before every subsequent lock (synchronized block or method
entry) of that same monitor. And because the happens-before relation
is transitive, all actions of a thread prior to unlocking
happen-before all actions subsequent to any thread locking that
monitor.
A write to a volatile field happens-before every subsequent read of that same field. Writes and reads of volatile fields have similar
memory consistency effects as entering and exiting monitors, but do
not entail mutual exclusion locking.
A call to start on a thread happens-before any action in the started thread.
All actions in a thread happen-before any other thread successfully returns from a join on that thread.
None of these seem to apply here. If some thread builds the list and passes its reference to some other threads without using locks (for example via a final or volatile field), I don't see what guarantees thread-safety. What am I missing?
Edit:
Yes, the write of the reference to the array is thread-safe on account of it being final. So that's clearly thread safe.
What I was wondering about were the writes of the individual elements. The elements of the array are neither final nor volatile. Yet they seem to be written by one thread and read by another without synchronization.
So the question can be boiled down to "if thread A writes to a final field, does that guarantee that other threads will see not just that write but all of A's previous writes as well?"
JMM guarantees safe initialization (all values initialized in the constructor will be visible to readers) if all fields in the object are final and there is no leakage of this from constructor1:
class RegularImmutableList<E> extends ImmutableList<E> {
final transient Object[] array;
^
RegularImmutableList(Object[] array) {
this.array = array;
}
}
The final field semantics guarantees that readers will see an up-to-date array:
The effects of all initializations must be committed to memory before
any code after constructor publishes the reference to the newly
constructed object.
Thank you to #JBNizet and to #chrylis for the link to the JLS.
1 - "If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are." - JLS §17.5.
As you stated: "Each action in a thread happens-before every action in that thread that comes later in the program's order."
Obviously, if a thread could somehow access the object before the constructor was even invoked, you would be screwed. So something must prevent the object from being accessed before its constructor returns. But once the constructor returns, anything that lets another thread access the object is safe because it happens after in the constructing thread's program order.
Basic thread safety with any shared object is accomplished by ensuring that whatever allows threads to access the object does not take place until the constructor returns, establishing that anything the constructor might do happens before any other thread might access the object.
The flow is:
The object does not exist and cannot be accessed.
Some thread calls the object's constructor (or does whatever else is needed to get the object ready to be used).
That thread then does something to allow other threads to access the object.
Other threads can now access the object.
Program order of the thread invoking the constructor ensures that no part of 4 happens until all of 2 is done.
Note that this applies just the same if things need to be done after the constructor returns, you can just consider them logically part of the construction process. And similarly, parts of the job can be done by other threads so long as anything that needs to see work done by another thread cannot start until some relationship is established with the work that other thread did.
Does that not 100% answer your question?
To restate:
How is this be thread safe? What guarantees the happens-before relationship between the writes performed in the Builder and the reads from RegularImmutableList?
The answer is whatever prevented the object from being accessed before the constructor was even called (which has to be something, otherwise we'd be completely screwed) continues to prevent the object from being accessed until after the constructor returns. The constructor is effectively an atomic operation because no other thread could possibly attempt to access the object while it's running. Once the constructor returns, whatever the thread that called the constructor does to allow other threads to access the object necessarily takes place after the constructor returns because, "[e]ach action in a thread happens-before every action in that thread that comes later in the program's order."
And, one more time:
If some thread builds the list and passes its reference to some other threads without using locks (for example via a final or volatile field), I don't see what guarantees thread-safety. What am I missing?
The thread first builds the list and then next passes its reference. The building of the list "happens-before every action in that thread that comes later in the program's order" and thus happens-before the passing of the reference. Thus any thread that sees the passing of the reference happens-after the building of the list completed.
Were this not the case, there would be no good way to construct an object in one thread and then give other threads access to it. But this is perfectly safe to do because whatever method you use to hand the object from one thread to another will establish the necessarily relationship.
You are talking about two different things in here.
Access to already built RegularImmutableList and its array is thread safe because there wont be any concurrent writes and reads to that array. Only concurrent reads.
The threading issue can happen when you pass it to another thread. But that has nothing to do with RegularImmutableList but with how other threads see reference to it.
Lets say one thread creates RegularImmutableList and passes its reference to another thread. For the other thread to see that the reference has been updated and is now pointing to new created RegularImmutableList you will need to use either synchronization or volatile.
EDIT:
I think the concern OP has is how JMM makes sure that whatever got written into the array after its creation from one building thread gets visible to other threads after its reference gets passed to them.
This happens by the use or volatile or synchronization. When for example reader thread assigns RegularImmutableList to volatile variable the JMM will make sure that all writes to array get flashed into main memory and when other thread reads from it JMM makes sure that it will see all flashed writes.
I've searched for this question and I only found answer for primitive type arrays.
Let's say I have a class called MyClass and I want to have an array of its objects in my another class.
class AnotherClass {
[modifiers(?)] MyClass myObjects;
void initFunction( ... ) {
// some code
myObjects = new MyClass[] { ... };
}
MyClass accessFunction(int index) {
return myObjects[index];
}
}
I read somewhere that declaring an array volatile does not give volatile access to its fields, but giving a new value of the array is safe.
So, if I understand it well, if I give my array a volatile modifier in my example code, it would be (kinda?) safe. In case of I never change its values by the [] operator.
Or am I wrong? And what should I do if I want to change one of its value? Should I create a new instance of the array an replace the old value with the new in the initial assignment?
AtomicXYZArray is not an option because it is only good for a primitive type arrays. AtomicIntegerArray uses native code for get() and set(), so it didn't help me.
Edit 1:
Collections.synchronizedList(...) can be a good alternative I think, but now I'm looking for arrays.
Edit 2: initFunction() is called from a different class.
AtomicReferenceArray seems to be a good answer. I didn't know about it, up to now. (I'm still interested in that my example code would work with volatile modifier (before the array) with only this two function called from somewhere else.)
This is my first question. I hope I managed to reach the formal requirements. Thanks.
Yes you are correct when you say that the volatile word will not fulfill your case, as it will protect the reference to the array and not its elements.
If you want both, Collections.synchronizedList(...) or synchronized collections is the easiest way to go.
Using modifiers like you are inclining to do is not the way to do this, as you will not affect the elements.
If you really, must, use and array like this one: new MyClass[]{ ... };
Then AnotherClass is the one that needs to take responsibility for its safety, you are probably looking for lower level synchronization here: synchronized key word and locks.
The synchonized key word is the easier and yuo may create blocks and method that lock in a object, or in the class instance by default.
In higher levels you can use Streams to perform a job for you. But in the end, I would suggest you use a synchronized version of an arraylist if you are already using arrays. and a volatile reference to it, if necessary. If you do not update the reference to your array after your class is created, you don't need volatile and you better make it final, if possible.
For your data to be thread-safe you want to ensure that there are no simultaneous:
write/write operations
read/write operations
by threads to the same object. This is known as the readers/writers problem. Note that it is perfectly fine for two threads to simultaneously read data at the same time from the same object.
You can enforce the above properties to a satisfiable level in normal circumstances by using the synchronized modifier (which acts as a lock on objects) and atomic constructs (which performs operations "instantaneously") in methods and for members. This essentially ensures that no two threads can access the same resource at the same time in a way that would lead to bad interleaving.
if I give my array a volatile modifier in my example code, it would be (kinda?) safe.
The volatile keyword will place the array reference in main memory and ensure that no thread can cache a local copy of it within their private memory, which helps with thread visibility although it won't guarantee thread safety by itself. Also the use of volatile should be used sparsely unless by experienced programmers as it may cause unintended effects on the program.
And what should I do if I want to change one of its value? Should I create a new instance of the array an replace the old value with the new in the initial assignment?
Create synchronized mutator methods for the mutable members of your class if they need to be changed or use the methods provided by atomic objects within your classes. This would be the simplest approach to changing your data without causing any unintended side-effects (for example, removing the object from the array whilst a thread is accessing the data in the object being removed).
Volatile does actually work in this case with one caveat: all the operations on MyClass may only read values.
Compared to all what you might read about what volatile does, it has one purpose in the JMM: creating a happens-before relationship. It only affects two kinds of operations:
volatile read (eg. accessing the field)
volatile write (eg. assignment to the field)
That's it. A happens-before relationship, straight from the JLS §17.4.5:
Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.
A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.
If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
These relationships are transitive. Taken all together this implies some important points: All actions taken on a single thread happened-before that thread's volatile write to that field (third point above). A volatile write of a field happens-before a read of that field (point two). So any other thread that reads the volatile field would see all the updates, including all referred to objects like array elements in this case, as visible (first point). Importantly, they are only guaranteed to see the updates visible when the field was written. This means that if you fully construct an object, and then assign it to a volatile field and then never mutate it or any of the objects it refers to, it will be never be in an inconsistent state. This is safe taken with the caveat above:
class AnotherClass {
private volatile MyClass[] myObjects = null;
void initFunction( ... ) {
// Using a volatile write with a fully constructed object.
myObjects = new MyClass[] { ... };
}
MyClass accessFunction(int index) {
// volatile read
MyClass[] local = myObjects;
if (local == null) {
return null; // or something else
}
else {
// should probably check length too
return local[index];
}
}
}
I'm assuming you're only calling initFunction once. Even if you did call it more than once you would just clobber the values there, it wouldn't ever be in an inconsistent state.
You're also correct that updating this structure is not quite straightforward because you aren't allowed to mutate the array. Copy and replace, as you stated is common. Assuming that only one thread will be updating the values you can simply grab a reference to the current array, copy the values into a new array, and then re-assign the newly constructed value back to the volatile reference. Example:
private void add(MyClass newClass) {
// volatile read
MyClass[] local = myObjects;
if (local == null) {
// volatile write
myObjects = new MyClass[] { newClass };
}
else {
MyClass[] withUpdates = new MyClass[local.length + 1];
// System.arrayCopy
withUpdates[local.length] = newClass;
// volatile write
myObjects = withUpdates;
}
}
If you're going to have more than one thread updating then you're going to run into issues where you lose additions to the array as two threads could copy and old array, create a new array with their new element and then the last write would win. In that case you need to either use more synchronization or AtomicReferenceFieldUpdater
I have a controller class that runs in thread A and composes a local variable list like this
Thread A
list = new ArrayList<Map<String, Order>>();
list.add(...);
list.add(...);
where Order is a java bean with several primitive properties like String, int, long, etc.
Once this list is constructed, its reference is passed to a UI thread (thread B) of Activity and accessed there. The cross-thread communication is done using a Handler class + post() method.
So the question is, can I access the list data from thread B without synchronization at all? Please note, that after constructed in thread A, the list will not be accessed/modified at all. It just exists like a local variable and is passed to thread B afterwards.
It is safe. The synchronization done at the message queue establishes a happens-before relationship. This of course assumes that you don't modify the Maps either afterwards. Also any objects contained in the maps, and so on must not be modified by other threads without proper synchronization.
In short, if the list and none of the data within it are not modified by other threads than B, you don't need any further synchronization.
It is not clear from the context you provide that where does this happen:
list = new ArrayList<Map<String, Order>>();
list.add(...);
list.add(...);
If it is in a constructor and list is final and the this reference does not leak from the constructor and you are absolutely sure that list won't change (for example by using the unmodifiableList decorator method) and the references to the Order instances are not accessible from elsewhere than it may be OK to not use synchronization. Otherwise you have Sword of Damocles over your head.
I mentioned the Order references because you may not get exceptions if you change them from somewhere else but it may lead to data inconsistency/corruption.
If you can guarantee that the list will not be modified then you don't need synchonization since all threads will always see the same List.
Yes, no need to synchronize if you're only going to read the data.
Note that even if thread A is going to eventually modify the list while thread B (or any other number of threads) is accessing it, you still do not have to synchronize because there's only one writer at any given time.
Sorry, the above statement is not completely correct. As stated in the JavaDoc:
If multiple threads access an ArrayList instance concurrently, and at
least one of the threads modifies the list structurally, it must be
synchronized externally. (A structural modification is any operation
that adds or deletes one or more elements, or explicitly resizes the
backing array; merely setting the value of an element is not a
structural modification.)
Also note I'm not taking into account element modification but purely list modifications.
I am new to multi-threading in Java and don't quite understand what's going on.
From online tutorials and lecture notes, I know that the synchronized block, which must be applied to a non-null object, ensures that only one thread can execute that block of code. Since an array is an object in Java, synchronize can be applied to it. Further, if the array stores objects, I should be able to synchronize each element of the array too.
My program has several threads updated an array of numbers, hence I created an array of Long objects:
synchronized (grid[arrayIndex]){
grid[arrayIndex] += a.getNumber();
}
This code sits inside the run() method of the thread class which I have extended. The array, grid, is shared by all of my threads. However, this does not return the correct results while running the same program on one thread does.
This will not work. It is important to realize that grid[arrayIndex] += ... is actually replacing the element in the grid with a new object. This means that you are synchronizing on an object in the array and then immediately replacing the object with another in the array. This will cause other threads to lock on a different object so they won't block. You must lock on a constant object.
You can instead lock on the entire array object, if it is never replaced with another array object:
synchronized (grid) {
// this changes the object to another Long so can't be used to lock
grid[arrayIndex] += a.getNumber();
}
This is one of the reasons why it is a good pattern to lock on a final object. See this answer with more details:
Why is it not a good practice to synchronize on Boolean?
Another option would be to use an array of AtomicLong objects, and use their addAndGet() or getAndAdd() method. You wouldn't need synchronization to increment your objects, and multiple objects could be incremented concurrently.
The java class Long is immutable, you cannot change its value. So when you perform an action:
grid[arrayIndex] += a.getNumber();
it is not changing the value of grid[arrayIndex], which you are locking on, but is actually creating a new Long object and setting its value to the old value plus a.getNumber. So you will end up with different threads synchronizing on different objects, which leads to the results you are seeing
The synchronized block you have here is no good. When you synchronize on the array element, which is presumably a number, you're synchronizing only on that object. When you reassign the element of the array to a different object than the one you started with, the synchronization is no longer on the correct object and other threads will be able to access that index.
One of these two options would be more correct:
private final int[] grid = new int[10];
synchronized (grid) {
grid[arrayIndex] += a.getNumber();
}
If grid can't be final:
private final Object MUTEX = new Object();
synchronized (MUTEX) {
grid[arrayIndex] += a.getNumber();
}
If you use the second option and grid is not final, any assignment to grid should also be synchronized.
synchronized (MUTEX) {
grid = new int[20];
}
Always synchronize on something final, always synchronize on both access and modification, and once you have that down, you can start looking into other locking mechanisms, such as Lock, ReadWriteLock, and Semaphore. These can provide more complex locking mechanisms than synchronization that is better for scenarios where Java's default synchronization alone isn't enough, such as locking data in a high-throughput system (read/write locking) or locking in resource pools (counting semaphores).
consider this class,with no instance variables and only methods which are non-synchronous can we infer from this info that this class in Thread-safe?
public class test{
public void test1{
// do something
}
public void test2{
// do something
}
public void test3{
// do something
}
}
It depends entirely on what state the methods mutate. If they mutate no shared state, they're thread safe. If they mutate only local state, they're thread-safe. If they only call methods that are thread-safe, they're thread-safe.
Not being thread safe means that if multiple threads try to access the object at the same time, something might change from one access to the next, and cause issues. Consider the following:
int incrementCount() {
this.count++;
// ... Do some other stuff
return this.count;
}
would not be thread safe. Why is it not? Imagine thread 1 accesses it, count is increased, then some processing occurs. While going through the function, another thread accesses it, increasing count again. The first thread, which had it go from, say, 1 to 2, would now have it go from 1 to 3 when it returns. Thread 2 would see it go from 1 to 3 as well, so what happened to 2?
In this case, you would want something like this (keeping in mind that this isn't any language-specific code, but closest to Java, one of only 2 I've done threading in)
int incrementCount() synchronized {
this.count++;
// ... Do some other stuff
return this.count;
}
The synchronized keyword here would make sure that as long as one thread is accessing it, no other threads could. This would mean that thread 1 hits it, count goes from 1 to 2, as expected. Thread 2 hits it while 1 is processing, it has to wait until thread 1 is done. When it's done, thread 1 gets a return of 2, then thread 2 goes throguh, and gets the expected 3.
Now, an example, similar to what you have there, that would be entirely thread-safe, no matter what:
int incrementCount(int count) {
count++;
// ... Do some other stuff
return this.count;
}
As the only variables being touched here are fully local to the function, there is no case where two threads accessing it at the same time could try working with data changed from the other. This would make it thread safe.
So, to answer the question, assuming that the functions don't modify anything outside of the specific called function, then yes, the class could be deemed to be thread-safe.
Consider the following quote from an article about thread safety ("Java theory and practice: Characterizing thread safety"):
In reality, any definition of thread safety is going to have a certain degree of circularity, as it must appeal to the class's specification -- which is an informal, prose description of what the class does, its side effects, which states are valid or invalid, invariants, preconditions, postconditions, and so on. (Constraints on an object's state imposed by the specification apply only to the externally visible state -- that which can be observed by calling its public methods and accessing its public fields -- rather than its internal state, which is what is actually represented in its private fields.)
Thread safety
For a class to be thread-safe, it first must behave correctly in a single-threaded environment. If a class is correctly implemented, which is another way of saying that it conforms to its specification, no sequence of operations (reads or writes of public fields and calls to public methods) on objects of that class should be able to put the object into an invalid state, observe the object to be in an invalid state, or violate any of the class's invariants, preconditions, or postconditions.
Furthermore, for a class to be thread-safe, it must continue to behave correctly, in the sense described above, when accessed from multiple threads, regardless of the scheduling or interleaving of the execution of those threads by the runtime environment, without any additional synchronization on the part of the calling code. The effect is that operations on a thread-safe object will appear to all threads to occur in a fixed, globally consistent order.
So your class itself is thread-safe, as long as it doesn't have any side effects. As soon as the methods mutate any external objects (e.g. some singletons, as already mentioned by others) it's not any longer thread-safe.
Depends on what happens inside those methods. If they manipulate / call any method parameters or global variables / singletons which are not themselves thread safe, the class is not thread safe either.
(yes I see that the methods as shown here here have no parameters, but no brackets either, so this is obviously not full working code - it wouldn't even compile as is.)
yes, as long as there are no instance variables. method calls using only input parameters and local variables are inherently thread-safe. you might consider making the methods static too, to reflect this.
If it has no mutable state - it's thread safe. If you have no state - you're thread safe by association.
No, I don't think so.
For example, one of the methods could obtain a (non-thread-safe) singleton object from another class and mutate that object.
Yes - this class is thread safe but this does not mean that your application is.
An application is thread safe if the threads in it cannot concurrently access heap state. All objects in Java (and therefore all of their fields) are created on the heap. So, if there are no fields in an object then it is thread safe.
In any practical application, objects will have state. If you can guarantee that these objects are not accessed concurrently then you have a thread safe application.
There are ways of optimizing access to shared state e.g. Atomic variables or with carful use of the volatile keyword, but I think this is going beyond what you've asked.
I hope this helps.