I need a method that will always be executed in one instance. For example, this method was called from different class instances and different threads at the same time. In this case, they should be executed one at a time, and not simultaneously, despite the fact that they are called from different instances.
I cant make it just static and synchronized, because it have a lot of inner code, which cant be refactored to static
For now I have next idea:
private static Boolean isMethodRun = false;
public void singletoneMethod() {
synchronized(Boolean) {
if (!isMethodRun) {
isMethodRun = true;
} else {
for (int i = 0; i < 10; i++) {
if (isMethodRun) {
Thread.sleep(2_000);
} else {
isMethodRun = true;
break;
}
}
}
}
try {
//inner code
} catch (Throwable e) {
//logs
throw e;
} finally {
isMethodRun = false;
}
}
Is there any prettier way to get such functionality
The easiest way would be to synchronize the method. Since you appear to have defined the isMethodRun variable static, it looks like you would want to synchronize on a static thing:
private static final Object lock = new Object();
public void singletoneMethod() {
synchronized (lock) {
// The code you want only to execute one-at-a-time.
}
}
You could have synchronized on the class - synchronized (WhateverYourClass.class) - but that is vulnerable to anybody in the JVM synchronizing on the class elsewhere. Using an inaccessible Object like this is more robust.
So basically you want only one singletonMethod call to proceed at a time1.
This is the simplest solution:
public static synchronized void singletonMethod() {
// your business logic here
}
You said:
I can't make it just static and synchronized, because it have a lot of inner code, which can't be refactored to static
I'm not convinced that it can't be refactored2, but if you say so, here are some alternatives:
private static final Object lock = new Object(); // Must be static!
public void singletonMethod() {
synchronized (lock) {
// your business logic here
}
}
Or
public static synchronized void oneAtATime(Runnable runnable) {
runnable.run();
}
You could use the oneAtATime method like this:
oneAtATime(() -> { // your business logic here }); // Java 8+
oneAtATime(new Runnable() {
public void run() {
// your business logic here
}
});
Apart from the first one (at the top), these alternatives all allow you to refer to instance variables in the "business logic". You just need to implement the "business logic" in the appropriate scope. (And even in the first case, it is trivial to pass an instance reference to a static method so that it can call methods on the instance.)
To use the above in a thread-safe fashion, you need to ensure that the "business logic" is all thread-safe. That will depend on other code in the application; e.g. how other threads / methods use any shared objects that this "business logic" is operating on.
why would static be needed here? Can't it just be public synchronized void singletonMethod? Or do the memory barriers not work for accessing static fields? – luk2302 25 mins ago
We need a static lock or a static synchronized method in order to meet the stated requirement that only one call is in progress at a time. If there is more than one lock, you won't get serialization.
It would be possible to implement the "one at a time" logic as a synchronized instance method of a (properly implemented) Singleton class. However, there is not much point unless you have other good uses for the Singleton class. (Bear in mind that the Singleton pattern brings problems of its own.)
1 - This is not what the term "singleton" conventionally means ...
2 - In fact the refactoring required is trivial. Just put your business logic into an instance method of YourClass declared as (say) businessLogic(). Then you can define the one-at-a-time method in YourClass as follows: static synchronized void singleton(YourClass arg) { arg.businessLogic(); }. You would typically use it (within YourClass) like this: YourClass.singleton(this);
Related
I have a class defined as:
class Artifacts {
private static boolean isThreadStarted = false;
private SomeClass someClass;
public static void startThread() {
isThreadStarted = true;
}
public static void setSomeClass(SomeClass = someClass1) {
if(isThreadStarted) {
someClass = someClass1;
}
}
public static SomeClass getSomeClass() {
return someClass;
}
}
Now the use case is that a method will make the value of isThreadStarted to be true. After that, a thread will start and using the value of someClass.There can be multiple threads setting and getting the value of someClass. I want to make this thread safe.
There is an annotation #ThreadSafe and there is a function synchronized static which I guess will do the thing. Please help in deciding the right approach.
Two simple improvements you can make to make this class more threadsafe for the intended purpose are to make the someClass field volatile, and to use AtomicBoolean for the isThreadStarted field.
class Artifacts {
private static AtomicBoolean isThreadStarted = new AtomicBoolean(false);
private volatile SomeClass someClass;
The volatile will ensure that any other thread that has a reference to an Artifact instance, does not cache the someClass instance. The JVM will always retrieve the someClass field from one main source. If volatile is not used, then other threads may cache someClass and changes it it may not be reflected across all the threads that are using it.
AtomicBoolean gives you volatile feature plus atomic operations, like check and set in the same operation. Here is a excerpt from the Javadoc.
A small toolkit of classes that support lock-free thread-safe programming on single variables. In essence, the classes in this package extend the notion of volatile values, fields, and array elements to those that also provide an atomic conditional update operation of the form:
So, your main concern is that multiple threads will read and write the someClass field (and maybe the isThreadStarted field, as well).
I don't know what the #ThreadSafe annotation does, it's not part of Java Standard Edition 8.
The basic way to make that thread-safe is to use the synchronized keyword. Typically, you'd encapsulate access to your field in getter and setter methods and make them synchronized.
public class Test {
private String someText;
public synchronized String getSomeText() {
return someText;
}
public synchronized void setSomeText(String someText) {
this.someText = someText;
}
}
But typically the multi-thread problems aren't tied to a single field.
If different threads of your program use a (thread-shared) object, you run into the risk that one thread modifies two fields A and B (e.g. moves money from A to B by subtracting from A and adding to B), and in-between some other thread reads A and B (e.g. calculates the current amount of A plus B) and sees an inconsistent state (amount subtracted from A, but not yet added to B).
The classical solution is to ensure that of all these code sections where the instance is read or modified, only one at a time is allowed to run. And that's what synchronized does.
Life_Hacker,
1st way
use static synchronized keyword with function to make Class Level lock in multithreading environment.
example :
public static synchronized void setSomeClass(Artifacts.class) {
if(isThreadStarted) {
someClass = someClass1;
}
}
2nd way
inside function definition, you can create Synchronize Block
example:
public static void setSomeClass(SomeClass = someClass1) {
synchronized(this){
if(isThreadStarted) {
someClass = someClass1;
}
}
}
2nd way is best approach
According to the Java Language Specification, constructors cannot be marked synchronized because other threads cannot see the object being created until the thread creating it has finished it. This seems a bit odd, because I can indeed have another thread view the object while it's being constructed:
public class Test {
public Test() {
final Test me = this;
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
}
}.start();
}
}
I know that this is a pretty contrived example, but it seems in theory that someone could come up with a more realistic case where marking the constructor synchronized would be legitimate in order to prevent races with threads like this one.
My question is this: is there a reason that Java would specifically disallow the synchronized modifier on a constructor? Perhaps my above example is flawed, or perhaps there really is no reason and it's an arbitrary design decision. In either case, I'm really curious and would love to know the answer.
If you really need synchronization of the rest of the constructor versus any threads which anyhow gets a reference to your not-yet-totally-constructed object, you can use a synchronized-block:
public class Test {
public Test() {
final Test me = this;
synchronized(this) {
new Thread() {
#Override
public void run() {
// ... Reference 'me,' the object being constructed
synchronized(me) {
// do something dangerous with 'me'.
}
}
}.start();
// do something dangerous with this
}
}
}
Usually it is considered bad style to "give out" your not-yet-constructed object like this, so a synchronized constructor is not necessary.
In some corner cases a synchronized constructor would be useful. Here is a more realistic example, from the discussion of Bozho's answer:
public abstract class SuperClass {
public SuperClass() {
new Thread("evil") { public void run() {
doSomethingDangerous();
}}).start();
try {
Thread.sleep(5000);
}
catch(InterruptedException ex) { /* ignore */ }
}
public abstract void doSomethingDangerous();
}
public class SubClass extends SuperClass {
int number;
public SubClass () {
super();
number = 2;
}
public synchronized void doSomethingDangerous() {
if(number == 2) {
System.out.println("everything OK");
}
else {
System.out.println("we have a problem.");
}
}
}
We want that the doSomethingDangerous() method is only called after construction of our SubClass object is complete, e.g. we only want the "everything OK" output. But in this case, when you only can edit your SubClass, you have no chance of achieving this. If the constructor could be synchronized, it would solve the problem.
So, what we learn about this: never do something like I did here in the superclass constructor, if your class is not final - and don't call any non-final methods of your own class from your constructor.
The question has been raised on a discussion list used by the writers of the Java concurrent API and the Java Memory Model. Several answers were given, in particular Hans Boehm replied:
Some of us (myself included IIRC) actually argued during the Java memory model deliberations that synchronized constructors should be allowed. Now I could go either way on it. Client code shouldn't use races to communicate the reference, so it shouldn't matter. But if you don't trust the clients of [your class], I think synchronized constructors could possibly be useful. And that was much of the reasoning behind final field semantics. [...] As David said, you can use synchronized blocks.
Because synchronized guarantees that actions on the same objects are not to be performed by multiple threads. And when the constructor is called you still don't have the object. It is logically impossible for two threads to access the constructor of the same object.
In your example, even if a method is invoked by the new thread, it is no longer about the constructor - it is about the target method being synchronized or not.
Constructor Modifiers section in JLS clearly says
There is no practical need for a constructor to be synchronized, because it would
lock the object under construction, which is normally not made available to other
threads until all constructors for the object have completed their work.
So there is no need for constructor to be synchronized.
Also it is not recommended to give out the objects reference(this) before object is created. One of the possible ambiguous situations would be to give out the objects reference is superclass constructor when subsclass object is being created.
In your example, the constructor is only actually called once from one thread.
Yes, it is possible to get a reference to an incompletely constructed Object (some discussions around double check locking and why it is broken reveal this problem), however, not by calling the constructor a second time.
Syncronized on the constructor would prevent two threads from calling the constructor on the same Object simultaneously, and that is not possible, as it is never possible to call the constructor on an object instance twice, period.
I see little reason to forbid constructors to be synchronized. It would be useful in many scenarios in multi-threaded applications. If I understand the Java Memory Model correctly (I read http://jeremymanson.blogspot.se/2008/11/what-volatile-means-in-java.html) the following simple class could have benefited from a synchronized constructor.
public class A {
private int myInt;
public /*synchronized*/ A() {
myInt = 3;
}
public synchronized void print() {
System.out.println(myInt);
}
}
In theory, I believe a call to print() could print "0". This could happen if an instance of A is created by Thread 1, the reference to the instance is shared with Thread 2, and Thread 2 calls print(). If there is no special synchronization between the write myInt = 3 of Thread 1 and the read of the same field by Thread 2, Thread 2 is not guaranteed to see the write.
A synchronized constructor would fix this issue. Am I right about this?
The following code can achieve the expected result for synchronized constructor.
public class SynchronisedConstructor implements Runnable {
private int myInt;
/*synchronized*/ static {
System.out.println("Within static block");
}
public SynchronisedConstructor(){
super();
synchronized(this){
System.out.println("Within sync block in constructor");
myInt = 3;
}
}
#Override
public void run() {
print();
}
public synchronized void print() {
System.out.println(Thread.currentThread().getName());
System.out.println(myInt);
}
public static void main(String[] args) {
SynchronisedConstructor sc = new SynchronisedConstructor();
Thread t1 = new Thread(sc);
t1.setName("t1");
Thread t2 = new Thread(sc);
t2.setName("t2");
t1.start();
t2.start();
}
}
Such a synchronization might make sense in some very rare cases, but I guess, it's just not worth it:
you can always use a synchronized block instead
it'd support coding in a pretty strange way
on what should it synchronize? A constructor is a sort-of static method, it works on an object but gets called without it. So synchronizing on the class also makes (some) sense!
When in doubt, leave it out.
Note that constructors cannot be synchronized — using the synchronizedkeyword with a constructor is a syntax error. Synchronizing constructors doesn't make sense, because only the thread that creates an object should have access to it while it is being constructed.
I have a Static helper class implemented that helps cache and retreive some read-only, non-mutable, non-volatile data from the database.
(Stripped) Example:
public class CacheHelper
{
private static HashMap foos, bars;
public static Foo getFoo(int fooId) { /* etc etc */ }
public static Bar getBar(int barId) { /* etc etc */ }
public static void reloadAllCaches()
{
//This is where I need it to lock access to all the other static methods
}
}
The way I've read it for static classes, If I add the synchronized keyword to the reloadAllCaches() method, this will apply a lock on the entire class while that method executes. Is this correct? (Edit: Yep, not correct. Thanks for the responses. )
Note: I would like to remain agnostic to the thread safety of the getter methods and the objects they return as this data is never mutated and would like it to be returned as fast as possible.
If you add the synchronized keyword to the reloadAllCaches() function all other static functions in the class that got the synchronized keyword can't execute while the reloadAllCaches() function is running.
How ever non-static functions can execute, not matter if they got the synchronized keyword or not. Also all other functions without the synchronized keyword can execute.
After all a function with the synchronized can be looked at like:
public class Bar
{
public static void foo()
{
synchronized (Bar.class)
{
// your code
}
}
}
A non-static function with the synchronized keyword can be looked at like this:
public class Bar
{
public void foo()
{
synchronized (this)
{
// your code
}
}
}
So static and non-static functions have a different synchronization context and do not block the execution of each other with the synchronized keyword.
For your case I suggest the usage of a ReentrantReadWriteLock. This class will allow any number of functions to get a read-lock at the same time but only one function to get a Write-Lock. The write lock is only acquired when there is no read-lock in place and no read-lock is acquired as long as a write-lock is in place.
You can make your reload function fetching a write-lock and all your reading function fetching a write-lock. You have to use a static instance of the ReentrantReadWriteLock of cause.
My proposal is to implement it like this:
public class CacheHelper
{
private static HashMap foos, bars;
private static java.util.concurrent.locks.ReadWriteLock lock = new java.util.concurrent.locks.ReentrantReadWriteLock();
public static Foo getFoo(int fooId)
{
lock.readLock().lock();
try {
/* etc etc */
} finally {
lock.readLock().unlock();
}
}
public static Bar getBar(int barId)
{
lock.readLock().lock();
try {
/* etc etc */
} finally {
lock.readLock().unlock();
}
}
public static void reloadAllCaches()
{
lock.writeLock().lock();
try {
//This is where I need it to lock access to all the other static methods
} finally {
lock.writeLock().unlock();
}
}
}
No, this isn't correct. Adding synchronized to only the reloadAllCaches method means that callers of that method must acquire the lock on the class, but threads calling non-synchronized methods can still access the class concurrently. You still need the accessors to be synchronized on the same lock for this to be safe, otherwise the reader threads may not see the latest changes and will get stale data. Alternatively you could use ConcurrentHashMap.
If you want the ability to re-populate the collections without locking them, youc an replace them with immutable collections.
private static volatile Map foos, bars;
public static Foo getFoo(int fooId) { return foos.get(fooId); }
public static Bar getBar(int barId) { /* etc etc */ }
public static void reloadAllCaches()
{
Map newFoo = ...
// populate newFoo
foos = newFoo;
Map newBar = ...
// populate newBar
bars = newBar;
}
getFoo will see a complete consistent copy without the need for locks as the Map is always replaced, never modified.
synchronized locks objects not methods, in this case you are locking the CacheHelper.class object
To make the getters fast as possible, you can use a ConcurrentHashMap instead of using synchronized
An example of using synchronized only for updates.
final ConcurrentMap<Key, ExpensiveObject> map =
public ExpensiveObject getOrNull(Key key) {
return map.get(key);
}
public ExpensiveObject getOrCreate(Key key) {
synchronized(map) {
ExpensiveObject ret = map.get(key);
if (ret == null)
map.put(key, ret = new ExpensiveObject(key));
return ret;
}
}
Rather than applying lock on CacheHelper Class object(CacheHelper.class) in reloadAllCaches() you can apply this lock inside this method on some piece of code because all methods i see are static and if you make them all synchronized then all threads will be blocked if any thread is accessing any method.
In simple terms the lock only prevents other threads from running the same method at the same time, it does not provide any locking resources over any other content in the class, static or otherwise.
Other threads will block access to the method only until the thread that has control exits that method. Access to anything else is still free for all threads.
If you need locking control over the object itself then you'll need to consider providing thread safe accessors or some kind of succession processing for the cache.
By that I mean that if you construct a new cache within this method, and once constructed replace the referenced objects in the cache helper with those new objects, then simply synchronising the reloadAllCaches method will be all you'll need to do.
However, if your intention is to reuse/recycle the existing cache containers then you will have to use locking at the container level to prevent reads while the cache is being destroyed and reconstructed.
If your neeeding to reload multiple cached maps (as per your example) then you may find it necessary to abstract away the cached objects another layer otherwise you might get out of sync access to the caches as you re apply them.
I have a class which contains a static field that acts like a singleton :
public class A {
private static MyAPI instance = null;
protected synchronized static MyAPI getAPI() throws Exception {
if (instance == null){
// init API;
}
return instance;
}
// other methods
}
And I have multiple classes which inherit from the class A and needs to perform actions on the API. I work in a multi-threaded environment and the API can work once at a time, so I have to ensure that all the subclasses don't work on the API at the same time. To do that, I synchronize the super class when I access the API in subclasses :
public class B extends A {
public void myMethod(){
synchronized (A.class) {
myAPI = getAPI();
// do stuffs with myAPI
}
}
}
With this solution, I lock the entire class instead of just the API instance, so the other methods of my class A are not available when a subclass work on the API and performances can be decreased.
Do you think this is the best solution or do you know a better way ?
Thanks.
There are two issues that I'd consider here:
First, because the MyAPI object acts as a singleton, the fact that other classes inherit from class A is irrelevant. You might as well just have other classes in a non-hierarchical structure refer to the singleton.
Secondly, the synchronization should be done inside the code of MyAPI, and this way you can control the synchronization granularity any way that you want. This lets you also achieve better encapsulation, and you don't need to worry about a bad-behaving caller who forgets to acquire a lock before proceeding. It can be per method, per functionality, etc.
For example:
class MyAPI {
public synchronized void doWork1() { // class level lock
...
}
public void doWork2 {
synchronized (someLockObject) {
...
}
}
public void doWork3 { // related to doWork2, lock the same object
synchronized (someLockObject) {
...
}
}
If you don't want to lock on the entire class, you may lock on a static object that you use only in that method:
public class A {
private static MyAPI instance = null;
protected static Object lockForMyMethod = new Object(); //have a static lock
// other methods
}
public class B extends A {
public void myMethod(){
synchronized (A.lockForMyMethod) { //do not lock on A.class
myAPI = getAPI();
// do stuffs with myAPI
}
}
}
Not sure why you need to lock down every access to your static member but consider using AtomicReference and it's getAndSet() method for better performance.
I work in a multi-threaded environment and the API can work once at a time, so I have to ensure that all the subclasses don't work on the API at the same time.
Depending on your environment, consider to use the ExecutorService.
For example: you could use a ThreadPoolExecutor with a fixed thread-pool size of 1 and submit your jobs to that executor.
That way you can ensure your API is only used within the call() method of the Callable you submitted.
Since you have only one thread working, you don't have to worry about concurrent access of the API.
Again, i don't know the environment you are working so maybe it is a bad idea or simple not possible to solve the problem with a ExecutorService.
I know when you want to lock method to be executed by only one thread you declare it with synchronized keyword.
What about classes, how to provide a lock on an entire class of objects when a thread
is executing some code on an instance of that class?
In other words, when a thread is executing a method on an object, no other thread should be
allowed to execute the same method even on a different instance of the same class.
You synchronize on a specific object, either some designated static lock object, or the class object (which happens when static methods are declared to be synchronized):
class X {
private static final Object lock = new Object();
public void oneAtATime() {
synchronized (lock) {
// Do stuff
}
}
}
class Y {
public void oneAtATime() {
synchronized (Y.class) {
// Do stuff
}
}
}
Each variant has its own pros and cons; locking on the class allows other code, outside of the class, to use the same lock for its own reasons (which allows it to orchestrate more high-level synchronization than what you provide) while the static final Object lock approach lets you prohibits it by making the lock field private (which makes it easier to reason about the locking and avoid your code from deadlocking because someone else wrote bad code).
You could of course also use some synchronization mechanism from java.util.concurrent, like explicit Locks, which provide more control over locking (and ReentrantLock currently performs a little better than implicit locks under high contention).
Edit: Note that static/global locks aren't a great way to go - it means every instance of the class ever created will essentially be tied to every other instance (which, aside from making it harder to test or read the code, can severely harm scalability). I assume you do this to synchronize some kind of global state? In that case, I'd consider wrapping that global/static state in a class instead, and implement synchronization per-instance rather than globally.
Instead of something like this:
class Z {
private static int state;
public void oneAtATime(){
synchronized (Z.class) {
state++;
}
}
}
Do it like this:
class State {
private int value;
public synchronized void mutate(){ value++; }
}
class Z {
private final State state;
public Z(State state){
this.state = state;
}
public void oneAtATime(){
state.mutate();
}
}
// Usage:
State s1 = new State(), s2 = new State();
Z foo = new Z(s1);
Z bar = new Z(s1);
Z frob = new Z(s2);
Z quux = new Z(s2);
Now foo and bar are still tied to each other, but they can work independently from frob and quux.
If you use static synchronized methods, they are locked via the Class Lock. You can also declare a static Object in the class and lock that in a method I believe via something like:
private static final Object STATIC_LOCK = new Object();
private void foo() {
synchronized (STATIC_LOCK) {
//do stuff...
}
}
You could use a static Mutex inside that method. So any concurrent thread is blocking inside the method while another is running it no matter what object of the class it belongs to. I don't think there is any special single keyword to produce the same effect like synchronized.
It is a rather aggressive synchronization, I would avoid it as much as possible.
Synchronize on static field of your class, or the class itself:
synchronized(MyClass.class) {
// mutually excluded method body
}
Both threads must use this construction
public void someMethod() {
synchronized(ClassThatShouldBeProtected.class) {
someSynchronizedCode();
}
}
This approach benefits from the fact, that class itself is an object and therefore it has a monitor. Then you don't need any artificial static instance.
There is no built-in mechanism for this. Create your own static lock attribute, and make sure you lock it and unlock it in every method. Don't forget about exceptions - make sure you unlock it in the "finally" sections.
This should work:
public class MyClass {
void synchronizedMethod() {
synchronized (MyClass.class) {
// synchronized on static level
}
}
}
Which 'missuses' the class's runtime-representation for locking. This is possible as any object can be used as a mutex in Java.
http://www.janeg.ca/scjp/threads/synchronization.html
talks about several ways to achieve it.
in general, locks are prohibitive and hinder benefits of threading. so the critical code should be minimized as much as its possible.
do you want a class lever lock to access static variables of the class or is it for protecting access to a common external resource the class? in which case you should proly have a separate lock while accessing it.