Lets say I have a code like this in my servlet:
private static final String RESOURCE_URL_PATTERN = "resourceUrlPattern";
private static final String PARAM_SEPARATOR = "|";
private List<String> resourcePatterns;
#Override
public void init() throws ServletException {
String resourcePatterns = getInitParameter(RESOURCE_URL_PATTERN);
this.resourcePatterns = com.google.common.base.Splitter.on(PARAM_SEPARATOR).trimResults().splitToList(resourcePatterns);
}
Is this thread safe to use 'resourcePatterns' if it will never be modified?
Lets say like this:
private boolean isValidRequest(String servletPath) {
for (String resourcePattern : resourcePatterns) {
if (servletPath.matches(resourcePattern)) {
return true;
}
}
return false;
}
Should I use CopyOnWriteArrayList or ArrayList is OK in this case?
Yes, List is fine to read from multiple threads concurrently, so long as nothing's writing.
For more detailed information on this, please see this answer that explains this further. There are some important gotchas.
From java concurrency in practice we have:
To publish an object safely, both the reference to the object and the
object's state must be made visible to other threads at the same time.
A properly constructed object can be safely published by:
Initializing an object reference from a static initializer. Storing a
reference to it into a volatile field. Storing a reference to it into
a final field. Storing a reference to it into a field that is properly
guarded by a (synchronized) lock.
your list is neither of these. I suggest making it final as this will make your object effectively immutable which in this case would be enough. If init() is called several times you should make it volatile instead. With this I of course assume that NO changes to the element of the list occur and that you don't expose any elements of the list either (as in a getElementAtPosition(int pos) method or the like.
Related
I was reading about Immutable objects in java.
There is a statement which states - "Immutable objects are thread-safe".
I need more clarification for the above statement:
If I have a shared resource of type 'String' which is shared with multiple threads (say 3)
And if one of the thread make changes to the shared reference, it will create a new String object and that will available only with that Thread object and other threads will not get to know about the changes made by one of the thread.
Will it not lead to data inconsistency?
So could anyone please help me understand this?
Thanks in advance.
An object of an immutable class is always thread-safe. However, the reference to such an object doesn't have anything to do with that. It might be or it might not be thread-safe, depending on how the class that contains the reference to this thread-safe object (a String object, for example) and the methods to manipulate such a reference.
See this example below, to illustrate the explanation:
public class User {
private string name;
public User(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
}
So, even though String is an immutable and thread-safe class, the reference to it in the class User above isn't thread-safe because its methods could be concurrently changing this reference to new String objects.
If you wanted it to be thread-safe, there would be many options. One of them would be to set all methods that can change the name object as synchronized.
Immutable types (in any language) are special reference types.
Their uniqueness lies in the fact that when they are changed they are replaced with an entirely new instance which reflects the previous state + the change
Lets say 2 threads running a function which receive an immutable reference type object as a parameter ( and of course i'll use string for this example)
// pseudo code !!
main()
{
var str = "initialState";
new Thread(Do,str,1).Start();
new Thread(Do,str,2).Start();
}
void Do(string arg,int tid)
{
int i = 0;
while(true)
{
arg += "running in thread " + tid + "for the " + i + "time";
Console.WriteLine(arg);
}
}
This program while print in parallel the number of occurrences running in each thread with out effecting what was printed in the other thread.
Why ?
If you think about it string is a reference type, it is passed by reference and not by value, meaning it is not copied only a copy of the reference occurs.
And yet though it was initially the same object. after the first change it is no longer and a different one is created.
If it was still the same object after changes it would be a shared resource between the 2 threads and will disrupt the state those threads men't to print.
Below is the code snippet from concurrency in practice.
class OneValueCache {
private final BigInteger lastNumber;
private final BigInteger[] lastFactors;
public OneValueCache(BigInteger i,BigInteger[] factors) {
lastNumber = i;
lastFactors = Arrays.copyOf(factors, factors.length);
}
public BigInteger[] getFactors(BigInteger i) {
if (lastNumber == null || !lastNumber.equals(i))
return null;
else
return Arrays.copyOf(lastFactors, lastFactors.length);
}
}
//Volatile is not enough to make VolatileCachedFactorizer thread safe? Why we need final specifier in OneValueCache.
public class VolatileCachedFactorizer implements Servlet {
private volatile OneValueCache cache = new OneValueCache(null, null);
//Servlet service method.
public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = cache.getFactors(i);
//Check factors are null or not.
if (factors == null) {
factors = factor(i);
cache = new OneValueCache(i, factors);
}
encodeIntoResponse(resp, factors);
}
}
What is the use of declaring fields as final in OneValueCache. "volatile OneValueCache cache" makes sure that object is visible to all the other threads and i assume that writes before volatile write is visible to all the other threads.
Final fields make OneValueCache immutable, thereby making it thread safe. They also have special semantics defined by the JLS, in particular, any thread will be able to see the correctly constructed object with the final fields initialized to its only correct value.
If this was not the case, and the fields happened to not be final, other threads might not be able to see the changes, even made in the constructor, because without final fields, there are no construction safety guarantees.
JCIP explains that OneValueCache is only an immutable reference class used to hold to the two bits of data. This is safer than updating two fields in the method, as it is not atomic. Then, OneValueCache is made volatile in the servlet because it needs to be changed, but is an atomic assignment, so no synchronization is needed.
They are two different things.
Generally,
volatile --> Creates a memory barrier which enforces the data in the cache to be flushed and forces data to be read from the main memory. So, all threads can always get the updated data for this particular field.
final -->
for primitives --> specifies that the value cannot change
for non-primitives --> The references cannot change (i.e, reference cannot point to another object).
For an object / field to be immutable, you need to ensure that it is transitively accessible by final fields and a reference of it doesn't escape.
PS : final and immutability are two different concepts. So, if you've heard of immutability, please understand that it is different from final.
It looks like the intention of OneValueCache class is to be immutable so declaring the values to be final just guarantees that at some later stage a programmer doesnt try to extend the class and overwrite the values.
java.lang.String is only effectively immutable. Brian Goetz of "Java Concurrency in Practice" said something like effectively immutable objects will only be thread safe if safely published. Now, say I unsafely publish String like this:
public class MultiThreadingClass {
private String myPath ="c:\\somepath";
//beginmt runs simultaneously on a single instance of MultiThreading class
public void beginmt(){
Holder h = new Holder();
h.setPath(new File(myPath)); //line 6
h.begin();
}
}
public class Holder {
private File path;
public void setPath(File path){
this.path = path;
}
public void begin(){
System.out.println(path.getCanonicalPath()+"some string");
}
}
At the moment that the MultiThreadingClass is initializing with its constructor, it could happen that the File constructor on line 6 may not see the value of myPath.
Then, about three seconds after the construction of the unsafely published String object, threads on MultiThreadingClass are still running. Could there still be a chance that the File constructor may not see the value of myPath?
Your statement that you are asking your question about:
At the moment that the MultiThreadingClass is initializing with its
constructor, it could happen that the File constructor on line 6 may
not see the value of myPath.
The answer is complicated.
You don't need to worry about the char-array value inside the String object. As I mentioned in the comments, because it is a final field that is assigned in the constructors, and because String doesn't pass a reference to itself before assigning the final field, it is always safely published. You don't need to worry about the hash and hash32 fields either. They're not safely published, but they can only have the value 0 or the valid hash code. If they're still 0, the method String.hashCode will recalculate the value - it only leads to other threads recalculating the hashCode when this was already done earlier in a different thread.
The reference myPath in MultiThreadingClass is not safely published, because it is not final. "At the moment that the MultiThreadingClass is initializing with its constructor", but also later, after the constructor completed, other Threads than the thread that ran the constructor may see the value null in myPath rather than a reference to your string.
There's an example in the Java Memory Model section of the Java Language Specification [version 8 linked but this is unchanged since JMM was released in JSR-133]:
Example 17.5-1. final Fields In The Java Memory Model
The program below illustrates how final fields compare to normal fields.
class FinalFieldExample {
final int x;
int y;
static FinalFieldExample f;
public FinalFieldExample() {
x = 3;
y = 4;
}
static void writer() {
f = new FinalFieldExample();
}
static void reader() {
if (f != null) {
int i = f.x; // guaranteed to see 3
int j = f.y; // could see 0
}
}
}
The class FinalFieldExample has a final int field x and a non-final
int field y. One thread might execute the method writer and another
might execute the method reader.
Because the writer method writes f after the object's constructor
finishes, the reader method will be guaranteed to see the properly
initialized value for f.x: it will read the value 3. However, f.y is
not final; the reader method is therefore not guaranteed to see the
value 4 for it.
This is even likely to happen on a heavily loaded machine with many threads.
Workarounds/solutions:
Make myPath a final field (and don't add constructors that pass out the this reference before assigning the field)
Make myPath a volatile field
Make sure that all threads accessing myPath synchronize on the same monitor object before accessing myPath. For example, by making beginmt a synchronized method, or by any other means.
Could there still be a chance that the File constructor may not see the value of myPath?
Answer is yes it is possible since Java Memory Model guarantees visibility of only final fields
:-
"A new guarantee of initialization safety should be provided. If an object is properly constructed (which means that references to it do not escape during construction), then all threads which see a reference to that object will also see the values for its final fields that were set in the constructor, without the need for synchronization."
JSR 133 Link
However I feel this situation is impossible to recreate (I too had tried earlier a similar theory but ended in vain).
There is a case of unsafe publication/escape of this reference within the constructor which can lead to the scenario of myPath not being initialized properly. An example for this is given in Listing 3.7 of the book you mentioned. Below is an example of making your class this reference to escape in constructor.
public class MultiThreadingClass implements Runnable{
public static volatile MultiThreadingClass unsafeObject;
private String myPath ="c:\\somepath";
public MultiThreadingClass() {
unsafeObject = this;
.....
}
public void beginmt(){
Holder h = new Holder();
h.setPath(new File(myPath)); //line 6
h.begin();
}
}
The above class can cause other threads to access unsafeObject reference even before the myPath is correctly set but again recreating this scenario might be difficult.
I have a service class that is an implementation of an interface and it's annotated with Spring as a service and a singleton. I have two different methods where each creates a string builder local variable. I have a private method that takes a string builder and a string, and both parameters are final variables. This private method appends information to that string builder depending on the information found in that additional string variable. In each implemented method I call that private method passing the locally created string builder and the necessary string.
I am confident that the two implemented methods are thread safe, but I am unsure about the private method. Is that string builder thread safe when I pass it like that? Does having the parameters as final help? I assumed the final made that thread safe, but at the same time I thought having it final means I couldn't append anything to it.
This stackoverflow question and answer says it wouldn't be, but in the example the parameter is not final, but maybe that does not matter.
Is that StringBuilder variable thread safe in this code?
Here's an example of what I have:
#Service
#Scope("singleton")
public class SingletonService {
#Override
public String buildSelect(final Integer id){
StringBuilder sb = new StringBuilder("select * from table ");
Map<String,Object> properties = new HashMap<String,Object>();
addWhere(sb,properties,id);
return sb.toString();
}
#Override
public String buildCount(final Integer id){
StringBuilder sb = new StringBuilder("select count(id) from table ");
Map<String,Object> properties = new HashMap<String,Object>();
addWhere(sb,properties,id);
return sb.toString();
}
private void addWhere(final StringBuilder sb, final Map<String,Object> properties, final Integer id){
if(id != null){
sb.append("where id = :id);
properties.put("id",id);
}
}
}
final has absolutely no effect when used in the method signature other than making it so you can't accidentally assign something to the variable inside the method.
Other than that ... why wouldn't this code be thread safe?
The only thing you're passing in to your public methods is an Integer which is immutable and nothing else external to the methods is ever modified.
So yes, since there's no concurrency involved, this is threadsafe.
That said, it also doesn't make a lot of sense. You're creating a Map, putting something in it, then discarding it.
Yes, that is thread-safe.
Each thread gets its own stack where the variables are stored. In this case the variable is a reference, one for each thread, to the instance of StringBuilder created by that thread. The instances of StringBuilder will have been created in the heap and so could be shared but you would have to explicitly pass the reference between threads for that to happen.
If a public method of an object only uses parameters passed, and local variables, then
can we say that it is thread-safe?
A so called pure function is indeed thread safe, but only if there are absolutely no side effects (ie, objects passed in via parameters altered).
If local memeber variables are not modified and the state of passed parameters is not changed (i.e. via methods on those parameters), then it is thread safe.
Furthermore, if passed parameters are objects, making them final does not guarantee thread safety.
public class Foo{
private int count = 1;
public void incrementFoo(){
count += 1;
}
public int getFoo(){
return count;
}
}
private int multiplier = 5;
//Not safe
public static int calculateFoo(final Foo myFoo){
//you can still do this, even if myFoo is final
myFoo.incrementFoo();
return myFoo.getFoo() * multiplier;
}
Yes, it's thread safe. It can not interfere with invocations of other methods. (Unless it has some other nasty side effects.)
Any interleaving of the instructions of this method, and the instructions of any other method will be ok.
It depends. There are ways it can easily be not thread safe.
First, if any argument that is passed into the method is not thread safe and your method uses it in a multi-threaded manner without proper synchronization, it is not thread safe. For example,
// HashMap is not thread safe
public void foo(String key, HashMap<String,String> map) {
String value = map.get(key);
if (value == null) {
map.put(key, "new value");
}
}
Another possibility is if any object that was created within the method escapes the method. Consider the following:
public void foo() {
Map map = ...; // create and populate the map
ListenerQueue.getQueue().add(map); // there are listener threads waiting on this queue
// do some other work
}
If there are other threads that are waiting on this queue and start using the map object, then the map object has escaped, and is subject to the same thread-safety issues.