I'm facing an issue regarding Java method synchronization. Let's hope I can explain it briefly:
I have two different methods in two different classes, in two different packages. Something like:
Package1
|_Class1
\MethodA
Package2
|_Class2
\MethodB
Ok, so now I need to synchronize these two methods, which are not threads. So far, I have two different approaches:
Shared semaphore.
Create a shared static semaphore outside Package1 and Package2, something like:
package Package3;
public class SemaphoreClass {
public static Semaphore;
}
I don't really know if JVM would consider this a shared semaphore, anyway.
Synchronized (SharedClass.class).
Using a shared class to synchronize those two methods, something like:
public void MethodA() {
synchronized (SharedClass.class) {
//...
}
and
public void MethodB() {
synchronized (SharedClass.class) {
//...
}
Anyway, these are just approaches. I would like to hear what's the best way to implement what I'm trying to achieve. Having a shared semaphore for JVM would make things easier, but well, I know there must be a solution for this. Thanks in advance.
Both of your approaches should work, but I don't think locking on class is a recommended practices. Prefer locking on instances of Object, or use proper locks from java.util. Also, do not lock on String.
Alternatively, you could let instances of classes Class1 and Class2 can take a lock as parameter during instantiation:
class Class1 {
private final Object lock;
public Class1( Object lock ) { this.lock = lock }
public method() { synchronize( lock ) { } );
}
Then make sure that you create one lock (with new Object()) and pass it to the two instances of Class1 and Class2.
So basically, you've broken down the original problem in two: 1) the two classes do no share anything statically global, they just receive a parameter. 2) the clients of Class1 and Class2 must pass the correct lock. The client of Class1 and Class2 acts as the "orchestrator".
Related
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.
I have a Singleton : ABCSingleton. This has #Asynchronous methods on it.
Another Object : DecoratorForSingleton decorates the ABCSingleton. Delegates calls to Singleton.
2 separate objects, PQRService and XYZService, need access to ABCSingleton through the decorator.
I created 2 separate instances of DecoratorForSingleton for each - PQRService and XYZService. That was to avoid race conditions or to avoid issues coming out of multiple calls been made to the same instance.
Should I be creating only one instance of DecoratorForSingleton for the 2 objects, PQRService and XYZService ??
None of the classes extend Thread or implement Runnable.
Which one is the better approach ?
Thanks
From what I read you have something like
class Singleton {
static final Singleton INSTANCE = new Single();
}
public class Decorator {
public void foo(){
Singleton.INSTANCE.foo()
}
}
public class PQRService {
Decorator decorator = new Decorator();
}
public class XYZSerivce {
Decorator decorator = new Decorator();
}
If this is the case, you gain nothing from creating individual Decorator instances. Though they are local to the service instance, they share a potentially mutable Singleton.INSTANCE. You will still need to synchronize access to your Singleton.
For collection of smaller helper utility classes, I have created a general class MyUtils:
// MyUtils.java
public final class MyUtils
{
public static class Helper1 {};
public static class Helper2 {};
//...
}
This helper classes from inside MyUtils will be used in the other files of the package:
// MyClass1.java
public class MyClass1
{
private MyUtils.Helper1 help1 = new MyUtils.Helper1();
public void method ()
{
private MyUtils.Helper2 help2 = new MyUtils.Helper2();
}
}
To let them accessible, I have made them static inside MyUtils (which doesn't have any data/function member of its own). My code is thread safe before creating MyUtils.
My worry is, by making these inner classes staticwill they remain thread safe, when their multiple instances will exist across the files ? Or is their any bad implication am I missing due to making them static ?
Edit: I am not touching any shared variable inside the helper classes. My only concern was that will the instance of the static classes be thread safe (since they are static).
If you're asking whether these is any bad implication of going from:
public class Helper1 {}
...to:
public class MyUtils {
public static class Helper1 {}
}
Then no, there is not. The static keyword in this case is just "promoting" the nested inner class to a top-level class, so that you can instantiate it without needing an enclosing instance of MyUtils. Here is a passable article on the subject:
http://www.javaworld.com/javaworld/javaqa/1999-08/01-qa-static2.html
In essence, doing public static class X on a nested inner-class is the same as doing public class X in a standard top-level class.
There is no meaning to a "class" itself being thread-safe or not thread safe. Therefore, whether or not it is static is irrelevant.
When someone refers to a class being thread-safe or not thread-safe, they really mean that the functionalities provided by that class are thread-safe or not. Accordingly, it's what the inner classes do themselves that actually makes the difference.
There's nothing inherent about methods that make them unsafe to be reentrant. Problems arise when you start accessing shared variables, etc. So, for example, a member of the class accessed by the methods needs to be synchronized appropriately. But if the methods don't store any state, etc., then there's nothing stopping you from using them across multiple threads.
Hope that helps.
You will need to guard the access to help1 since this is an instance level (shared) variable.
While help2 is safe if you dont allow it to skip the method.
There is nothing special about the static classes and instance created out of it.
Same rules of thread safety applies to instances of static classes also which applies to normal cases.
static methods and inner classes don't have any access to the variables of their dynamic counter part, and consequently can't use monitors/synchronize on an instance of their parent class. Of course this doesn't mean that declaring them and using them is inherently non-thread safe. It's just that if you need to synchronize any of those static methods on an instance of the parent class, then you need to be sure that you synchronize/lock before entering them or else you must explicitly pass a reference to a parent instance into them.
I have got the answer. Making MyUtils an interface is more cleaner design, as I can get away with the static identifienr from the helper classes
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.
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.