In my case, the certain method may run under synchronized and asynchronous mode base on a condition.
What I do is use a reentrantlock to do the switch. The code looks like below.
private Lock modeLock = new ReentrantLock(true);
public void specialMethod(boolean condition)}
Callable<Result> c = () -> {
if(condition)
modeLock.lock();
else{
try {
modeLock.tryLock(1, TimeUnit.DAYS);
} catch (InterruptedException e) {
} finally {
modeLock.unlock();
}
//do something here
if(condition)
modeLock.unlock();
return result;
};
pool.submit(c);
}
It works for me but seems very stupid. I think I can improve it by Condition from the ReentrantLock but I don't have any clue. Could any one tell me how to improve it? Thx
You can perhaps use the synchronizedCollection(Collection<T> c) method from Java Collections as a pattern for what you are trying to do.
Define an interface for your class and achieve the synchronizaton by putting a wrapper around it that does the lock/unlock logic but delegates the business logic to your original unsynchronized class. Your wrapper would implement the interface (i.e., implement specialMethod) but would do and lock and unlock and then call the original class to do the actual logic.
Instead of passing the flag to the method, use the flag when you construct the object of the class to decide what type of class to contruct, the original one or the original plus a synchronization wrapper.
Alternatively (a slightly simpler approach), create an extension of your class (e.g. SynchronizedClassName extends ClassName) and override specialMethod. Do the locking there (unconditionally) and then call the logic in the superclass.
Again, decide which object to construct to switch between synchronized or unsynchronized.
If your synchronized wrapper exposes the unsychronized class it contains, you could access that if you wanted to switch between synchronized and unsynchronized access.
Example:
interface SpecialInterface {
void specialMethod();
}
// Original class
class SpecialClass implements SpecialInterface {
public void specialMethod() {
... // logic with no locking
}
class SynchronizedSpecialClass implements SpecialInterface {
private SpecialClass logic;
private Lock modeLock = new ReentrantLock(true);
public SynchronizedSpecialClass(SpecialClass logic) {
this.logic = logic;
}
public void specialMethod() {
try {
modeLock.lock();
logic.specialMethod();
} finally {
modelock.unlock();
}
}
}
// use
SpecialInterface o = new SpecialClass();
if (lockingRequired) o = new SynchronizedSpecialClass(o);
Related
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);
I'm using a public java API to build my multi thread application, but I don't know if some methods of this API are thread-safe [indeed I really think they aren't].
I was looking for the most clean and straight way to implement this safety on my code and decided to use lambda expression.
I'm planning to use something like this:
public class Myclass {
private NotThreadSafe obj;
public Myclass() {
this.obj = new NotThreadSafe();
}
private synchronized void useNonThreadSafeObject(FunctionalInterface r) {
r.exec(this.obj);
}
private void method1() {
this.useNonThreadSafeObject((NotThreadSafe p)->{/*do stuff*/};);
}
private void method2() {
this.obj.someMethod();
}
/* any other methods */
}
I want to make sure that no method in Myclass will call directly to 'obj'
so all methods must use obj as method1 do, avoiding directly call as method2
of course java doens't have a modifier to do it, but I was wondering if was an annotation or other way to check it at compiler time...
----[I wasn't clear at first time, trying to explain more]----
You can simply split the class into two:
class Guard {
private final NotThreadSafe obj;
public Guard() {
this.obj = new NotThreadSafe();
}
synchronized void useNonThreadSafeObject(FunctionalInterface r) {
r.exec(this.obj);
}
}
public class Myclass {
private Guard guard=new Guard();
private void method1() {
guard.useNonThreadSafeObject(p -> {/*do stuff with p*/});
}
private void method2() {
guard.useNonThreadSafeObject(p->{/*do other stuff with p*/});
}
/* any other methods */
}
This is the best isolation you can get as no direct access to obj is possible from MyClass. But note that this is not bullet-proof, it’s still possible to create a custom implementation of FunctionalInterface which will keep the received NotThreadSafe instance and store it somewhere in the heap for accessing it at a later time without the Guard. However, that’s a bigger effort and unlikely to happen accidentally…
I have a number of default methods in interfaces that need synchronization and it seems that only this is available:
default void addUniqueColumns(List<String> names) {
synchronized (this) {
... do something
}
}
The problem is, I want to synchronize on a private lock instead of this for better control:
default void addUniqueColumns(List<String> names) {
synchronized (lock) { // how to get a private lock in a default method??
... do something
}
}
Solutions? Clever workarounds? Or just live with it :) !
You can put the lock object into a pubic static field of a package-visible class, letting all your default methods share the lock. The lock remains visible inside your library, but since classes with default access are not visible outside your library, the lock would be private to the users of your interface outside your library:
class LockHolder { // Package private class
public static Object LOCK = new Object();
}
public interface ColumnCollection {
default void addUniqueColumns(List<String> names) {
synchronized (LockHolder.LOCK) {
... do something
}
}
}
As far as your library is concerned as a whole, this trick gives you the same advantages as using a private lock object does compared to synchronizing on this, because it prevents malicious code written by outsiders from accessing your lock. Of course the lock can be grabbed by any part of your library.
You could add a getLock() method to your interface and have each implementor return the object to lock over.
For the heck of it (and some entertainment value) let's see what might be feasable ...
I put the lock object into a static field of a package-visible class, letting all my default methods share the lock. A lock provider provides instances their own lock on-demand. The lock is removed from the collection when the instance is garbage collected.
The lock provider creates a lock the first time it is requested from an instance and then returns the same lock thereafter. It looks like this:
final class LockProvider {
private static final WeakHashMap<Widget,Object> widgetLocks = new WeakHashMap<>();
static Object obtainLock(Widget w) {
synchronized (widgetLocks) {
return locks.computeIfAbsent(w, x -> new Object());
}
}
}
And now the default interface method looks like this:
public interface Widget{
default void addSomething(List<String> names) {
synchronized (LockProvider.obtainLock(this)) {
... do something
}
}
}
One weakness of this is that the WeakHashMap uses Object.hashcode() and Object.equals(). Another is that, although fast, it is not super-high-performance. Although this way of doiung it seems clever ... any method that requires synchronization on a private lock would be better designed in another way.
[UPDATED]
What I did in the end was:
1) create default methods:
public interface Widget{
default void addSomething(List<String> something) {
... do something
}
}
2) Then created both regular and thread-safe implementations
public class WidgetImpl implements Widget{
...
}
// Threadsafe version
public class WidgetThreadsafeImpl implements Widget{
private final Object lock = new Object();
public void addSomething(List<String> something) {
synchronized(lock){
super.addSomething(something);
}
}
}
The default method provides an algorithm and the implementations can provide the thread-safe or non-thread-safe implementations.
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.