I could not find any definitive answer to my question elsewhere so I'm deciding to ask.
I am having porting code into Java and making it threadsafe. I'm applying as many getters/setters as I can on objects and passing them around. And obviously these values are not set as static. But I'm also looking at other angles.
For any particular thread I want all methods in a class to be able to access a class variable without other threads interfering (and WITHOUT synchronized variable keyword), is the following acceptable?
public class TestClass {
public double testVal;
public void methodA() {
testVal = 22.6;
}
public double methodB() {
return testVal;
}
}
If I create an instance of TestClass in main and call methodA then methodB on that object, it returns my testVal. This problem is to be scaled up with many many values shared across different methods in the class as i'm just showing a simple demo.
Is this a good threadsafe approach? This data would be stored on the thread stack rather than the heap if I'm correct?
Cheers
There are many ways to make your class thread safe.
1. You can make your variable as volatile as in the example you have asked , if the current state of testval does not depend upon the previous state
2. You make the variable as private and volatile and use synchronization for all the methods that are modifying the state of your object.
3. Make the class as immutable
4. Make the calss as stateless
5. Guard all the method with synchronized keyword that are modifying the state of the variables.
Related
I was reading about volatile when I came across this statement that using volatile and synchronize keyword would slow down your overall performance hence the following code to make a singleton class
public enum Singleton {
INSTANCE
}
Is better making a singleton class which includes a volatile instance and a synchronised method to return that static instance.
Though both the classes are thread safe and give the same desired result. Apart from the code readability , are there are any performance benefits of using enums.
Maybe volatile does not do what you think it does. The text of your question looks like you are asking about two different ways of safely publishing a singleton in a multi-threaded environment. But, that is not what volatile is for. volatile solves a more general problem.
You can declare a variable to be volatile if it needs to be shared between different threads, but it does not need to be synchronized with any other variable. The volatile declaration ensures that any time a thread looks at the variable, it always will see the newest value that was assigned to it, even if that value was assigned by some other thread.
Yes. volatile is costly. It would be a mistake to use it when you don't need it (e.g., it would be a mistake to use it on a variable that is not shared, and it would be a mistake to use it on a shared variable that already is protected by other means.)
synchronized keyword by definition slow down the performance as it allows only one thread to process the synchronized code block. The only reason to use synchronized and volatile for creating a singleton class is to provide for lazy initialization of the single instance of the class.
private static volatile ThreadSafeLazySingleton instance;
private ThreadSafeLazySingleton(){}
public static synchronized ThreadSafeLazySingleton getInstance(){
if(instance == null){
instance = new ThreadSafeLazySingleton();
}
return instance;
}
Lazy initialization is helpful when the instantiation is resource heavy and you want to delay the creation of instance to the last moment.
It is possible to break the singleton design of a class by using Reflection and setting the private constructor Singleton.class.getDeclaredConstructors() access to true by using constructor.setAccessible(true).
Using enum to design a singleton class overcomes the above drawback as Java ensures that enums are always instantiated only once. However, the benefits of lazy initialization are lost in this approach. As synchronization is not used, this approach will have better performance than the synchronized approach.
The best way to design a singleton class is by using the method suggested in this answer
I have a class as follows
class Myclass{
//no instance variables
static boolean validate(MyObj oj){
//impl
}
}
Now if 2 thread calls static method Myclass.validate(param) with different parameters at the same time ,will it work correctly? If yes/no, how?
Is my approach correct? I want to put some validation logic or some custom conversion utility in such static methods.
1- Call is safe since the obj parameter is local to the method. However ensure that
The Obj is not shared by different threads. If it is then sate is not
modified. (should be immutable)
The object re3fernce is not passed to any alien method, which
might be not thread safe.
You can mark the parameter as final.
2- Its OK to have static methods for classes which don't have any state.
If you don't have any instance variables, you have a utility class.
public enum Utility {;
public static boolean validate(MyObj obj) ....
}
However a better approach is to move the method to the first parameter type, if you can.
public class MyObj {
public boolean validate() ....
}
Provided the arguments are not shared, two threads can call the same method without thread safety issue.
If this is for validation, or conversion a utility class may be a better choice if you want more than one way to validate or convert the MyObj type.
You use case is a perfect fit for an Utility class and making the utility class methods static will help you use the class without instantiating it (Hence avoiding object littering and GC overhead ).
Thread safety is not an issue here as you are using any shared variable (class variables). So you are safe that way.
So both #1 and 2# will work.
Yes, it will work correctly. Parameters passed to a method lives in
a memory area called the "stack" and each thread will have it's own
stack.
I would say yes
I tried really hard to search for information about the issue, but nothing was relevant.
Any contribution will be appreciated.
DataStructure ds = new DataStructure();
public synchronized void run() { b(); }
private void b() { ds.update(); }
public synchronized void c() { ds.update(); }
Suppose that the above code is implemented using a thread.
as you might notice, there is a DataStructure object which is being shared and accessed through synchronized methods, when only one synchronized method can be called at any given time (I am not mistaken. right?).
Is there any possibility that the DataStructure object will be accessed through the public methods in unsynchronized manner?
thanks.
Your code is incomplete, but if the above is part of a Runnable or Thread, then no concurrency is possible with the given methods since you're synchronizing the entire run() method. Using threads is pretty pointless in that case.
I also don't see where the DataStructure would be shared between threads - looks like a separate one is created for each one. If it actually is shared, then access would not be synchronized because you synchronize on the Runnable or Thread rather than the shared object.
Without seeing more code, its very hard to tell. What is the class that those methods belong to? how are they invoked, and by what classes?
Concurrency problems are hard to diagnose, and harder if there isn't enough information.
What i assume you have are threads that execute the run() method above, and there are different threads that execute the c() method. The synchronization happens on the class that the above method resides, so there wouldn't be any problems (except slowness if lots of threads).
If
There is no other public method apart from what you wrote here, that has access to ds, and
"the DataStructure object" you are talking on is the object instance in a specific object instance of your class (instead of ALL DataStructure objects)
then what you are expecting is correct. There shouldn't be any concurrent access to ds through public methods of your class.
Honestly I don't see anything special in your class that make it different from normal synchronized method example.
Is the following code threadsafe ?
public static Entity getInstance(){
//the constructor below is a default one.
return new Entity();
}
Assuming the constructor itself is thread-safe, that's fine.
It would be very unusual for a constructor not to be thread-safe, but possible... even if it's calling the default auto-generated constructor for Entity, the base constructor may not be thread-safe. I'm not saying it's likely, just possible :)
Basically there's no magic thread-safety applied to static methods or instance methods or constructors. They can all be called on multiple threads concurrently unless synchronization is applied. If they don't fetch or change any shared data, they will generally be safe - if they do access shared data, you need to be more careful. (If the shared data is immutable or only read, that's generally okay - but if one of the threads will be mutating it, you need to be really careful.)
Only static initializers (initialization expressions for static variables and static { ... } blocks directly within a class) have special treatment - the VM makes sure they're executed once and only once, blocking other threads which are waiting for the type to be initialized.
It depends on the details of the Entity constructor. If the Entity constructor modifies shared data, then it is not.
It's probably thread safe, but what's the point? If you're just using a factory method to redirect to the default constructor then why not use the constructor in the first place? So the question is: what are you trying to achieve? The name getInstance() suggests a singleton (at least that's common practice), but you clearly don't have a singleton there. If you do want a singleton, use a static inner holder class like this:
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return InstanceHolder.INSTANCE;
}
private static final class InstanceHolder {
public static final Singleton INSTANCE = new Singleton();
}
}
but if you don't, why bother with such a factory method, as you're not adding any value (method name semantics, object pooling, synchronization etc) through it
Thread safety is about access to shared data between different threads. The code in your example doesn't access shared data by itself, but whether it's thread-safe depends on whether the constructor accesses data that could be shared between different threads.
There are a lot of subtle and hard issues to deal with with regard to concurrent programming. If you want to learn about thread safety and concurrent programming in Java, then I highly recommend the book Java Concurrency in Practice by Brian Goetz.
Multiple threads could call this method and each one will get an unique instance of 'Entity'. So this method 'per se' is thread safe. But if there is code in the constructor or in one of the super constructors that is not thread safe you might have a safety problem anyhow.
I'm creating a static class which is going to hold some vectors with info.
I have to make it synchronized so that the class will be locked if someone is editing or reading from the vectors.
What is the best way to do this?
Is it enough to have a function which is synchronized inside the class like this:
public synchronized insertIntoVector(int id)
{
}
Thanks in advance :)
Firstly, you need to define exactly what you mean by "static class". At first, I thought you meant a class where all methods were static (that wasn't meant to be instantiated) - but your code snippet implies this isn't the case.
In any case, synchronized methods inside the class are equivalent to synchronized(this) if they are instance methods, or synchronized(TheContainingClassName.class) if they're static methods.
If you are either creating a non-instantiable class with all static methods, or if you are creating a class that will act as a singleton, then synchronizing every method of the class will ensure that only one thread can be calling methods at once.
Do try to ensure that your methods are atomic though, if possible; calls to different methods can be interleaved by other threads, so something like a getFoo() call followed by a setFoo() (perhaps after incrementing the foo variable) may not have the desired effect if another thread called setFoo() inbetween. The best approach would be to have a method such as incrementFoo(); alternatively (if this is not possible) you can publish the synchronization details so that your callers can manually hold a lock over the class/instance during the entire sequence of calls.
AFAIK, there's no such thing as "static class" in Java. Do you mean a class that contains only static methods? If so, then
public static synchronized void insertIntoVector(int id) {
}
synchronizes with respect to the class object, which is sufficient, if there are only static methods and all of them are synchronized.
If you mean static inner class (where the word "static" has a different meaning than in static methods), then
public synchronized void insertIntoVector(int id)
{
}
synchronizes with respect to an instance of that static inner class.