As title, may I know do the waitForUnlock method exist Redisson? I search though internet and check the method one by one seem no method suit my use case. Below is the code how I make it. Do we have better option or I miss out something? Thanks.
public void methodA() {
RLock lock = redisson.getLock("myLock");
lock.lock(10, TimeUnit.SECONDS);
// action
lock.unlock();
}
public void methodB() {
waitForUnlock();
}
public void waitForUnlock() {
RLock lock = redisson.getLock("myLock");
while(lock.isLock()) {} // wait for unlock without create lock
// action;
}
Related
I have two methods both run by different threads, one of the methods i dont want to run when the other has been called. This is the reason I have chosen to use a lock
#Override
public synchronized void doSomething(int[] params)
{
while (lock.isLocked())
{
// wait for it to become unlocked
}
//lock is released so lets do some stuff
in my other method I have the following implementation
#Override
public void doSomethingElse(int param)
{
lock.lock();
for (int i = 0 ; i < param; i++)
{
//do some stuff
}
lock.unlock();
}
Is the while loop the correct way to say, I want this thread to wait here until the lock is released or is there a better way to implement this
Thanks
The while loop does busy waiting, which is definitely something you don't want to do.
Calling lock.lock(); will block until the lock is released, so it's the proper way to do it, just like you're doing in your other method.
You also don't need for the first method to be synchronized, and the lock should always be released in a finally clause.
You need something like this:
private void method1()
{
lock.lock();
try {
...
} finally {
lock.unlock();
}
}
private void method2()
{
lock.lock();
try {
...
} finally {
lock.unlock();
}
}
Don't forgeet to use try {} finally{} or you could end up with deadlock.
Both wrong, the standard practice is to unlock in the finally clause. Otherwise the application will stall if exception is thrown from inside the code where the lock applies:
public void doSomethingElse(int param) throws Exception {
lock.lock();
try {
//do some stuff that may throw exceptions
} finally {
lock.unlock();
}
}
I wonder what would be the most efficient solution to this problem.
I have a multithreaded database implementation (LevelDB, for example) and I want it to handle synchronization, since it can do it better. However, I want to initialize the database asynchronously, without blocking any thread unless they somehow want to use the database before it has been opened.
Something along the lines of:
public class Storage {
Database db;
public Storage() {
open();
}
private void open() {
new Thread(new Runnable() {
public void run() {
// attempt to open db here, i.e. change the value of Storage.db from null
// into Object
}
}).run();
}
public void accessMethod() {
// this method should only use a non-null Storage.db value, it should block
// until the thread above does not set the value of db to be an Object
}
public void nonAccessMethod() {
// this method is not concerned with the value inside Storage.db and should not
// block while the thread above is running
// example: memory cached operations on the db which will be executed after
// the thread above finishes and "unlocks" Storage.db
}
}
I came up with this solution, but it is not very efficient:
public class Storage {
ReentrantLock lock;
Database db;
public Storage() {
lock = new ReentrantLock();
open();
}
private void open() {
lock.lock(); // to be released in thread below
new Thread(new Runnable() {
public void run() {
// heavy work here while populating Storage.db
lock.unlock();
}
}).run();
}
// returns true if the database is not yet open and that we need to release
// the lock once our code segment completes
private boolean blockIfNotOpen() {
if (lock.tryLock()) {
lock.unlock(); // << this code segment sucks
return false;
} else {
lock.lock();
return true;
}
}
public void accessMethod() {
boolean wasNotOpen = blockIfNotOpen();
// "blocking" code here
if (wasNotOpen) {
lock.unlock();
}
}
public void nonAccessMethod() {
// not concerned with Storage.db and therefore not trying to lock
}
}
I don't like this solution because it still synchronizes access to the database in the implementation of Storage long after Storage.db has been populated, when in fact there is an underlying system inside DB which can handle concurrency better (example: DB exposes worker threads, etc.).
Synchronizing on the Storage object is not a solution since it will, well synchronize, all the time, instead of only when Storage.db is null.
Notes: I'm guaranteed that there will be no concurrent calls before Storage's constructor finishes, if you're worried about the lock. :) So, all concurrency happens after the constructor.
I think the solution would be using ReadWriteLock - writeLock().lock() in constructor, writeLock().unlock() after the db is initialized and the readLock() is used from the db consumers.
Another option, use Future:
public class Storage {
private final Future<Database> dbFuture = Executors.newSingleThreadExecutor().submit(
new Callable<Database>()
{
public Database call()
{
return new Database(...);//Long running DB initialisation
}
}
);
public void accessMethod()
{
Database db = dbFuture.get();// will wait while the call() is not completed yet.
}
}
I'm working on a multithreaded Java project where I would like to have objects that prevent their methods from being called from any thread for some period of time. Ideally, those method calls would not be thrown out, but simply queued up until the cooldown from the previous method has completed. Here's a simple example of a class with that kind of functionality:
public class A {
private synchronized void cooldown(long ms) {
long finishTime = ms + System.currentTimeMillis();
while (System.currentTimeMillis() < finishTime);
}
public synchronized void foo() {
// foo's code
cooldown(1000);
}
public synchronized void bar() {
// bar's code
cooldown(2000);
}
}
This works, but I'm expecting to have quite a few of the above objects and I feel like the loop inside of cooldown() is wasteful. I'd love to use a construct like Thread.sleep(), but in this case, that would have the undesirable effects of forcing the calling thread to sleep and not preventing any other thread from making method calls on A. Any suggestions?
EDIT:
To clarify, given the following implementation:
public synchronized void foo() {
System.out.println("foo");
cooldown(1000);
}
public synchronized void bar() {
System.out.println("bar");
cooldown(2000);
}
public static void main(String[] args) {
final A a = new A();
new Thread(new Runnable() {
public void run() {
a.foo();
}
}).start();
System.out.println("foobar");
new Thread(new Runnable() {
public void run() {
a.bar();
}
}).start();
}
I would like foo and foobar to print instantly (order doesn't matter), followed by bar a second later. If cooldown() just called Thread.currentThread().sleep(ms) instead of the current implementation, then foo would print instantly, followed by foobar and bar a second later.
I'd love to use a construct like Thread.sleep(), but in this case, that would have the undesirable effects of forcing the calling thread to sleep and not preventing any other thread from making method calls on A. Any suggestions?
I don't see the difference between calling Thread.sleep() versus your spin loop aside from the fact that the spin loop wastes CPU. If you are inside cooldown(...) then that instance of A is synchronized.
If you mean that you have other methods that are synchronized and you don't want the thread that is cooling down to be holding the lock then you can use this.wait(...) which will release the lock during the sleep. Of course is someone is calling notify(...) this won't work.
private synchronized void cooldown(long ms) {
try {
long waitUntilMillis = System.currentTimeMillis() + ms;
long waitTimeMillis = ms;
do {
this.wait(waitTimeMillis);
// we need this dance/loop because of spurious wakeups, thanks #loki
waitTimeMillis = waitUntilMillis - System.currentTimeMillis();
} while (waitTimeMillis > 0);
} catch (InterruptedException e) {
Thread.currentThread.interrupt();
}
}
The right thing to do is to not have synchronized methods and only synchronize when you specifically need to. Then you can cooldown easily without holding a lock.
private void cooldown(long ms) {
try {
this.sleep(ms);
} catch (InterruptedException e) {
Thread.currentThread.interrupt();
}
}
public void foo() {
synchronized (this) {
// foo's code
}
cooldown(1000);
}
You have following options:
Thread.sleep() should work fine if called inside synchronized method. All other threads would be prevented and your thread will hold lock and wait.
Use timed wait/notify in a synchronized block. That should also do the job.
EDIT:
See the below code
public class A {
final volatile Object lck = new Object();
volatile boolean waitStatus = true;
private void cooldown(long ms) {
synchronized(lck){
long startTime = System.currentTimeMillis();
//Do thread need to wait
if(waitStatus){
while(System.currentTimeMillis()-startTime < ms)
lck.wait(gapTime);
//Wait over no other thread will wait
waitStatus = false;
}
}
}
public void foo() {
// foo's code
cooldown(1000);
}
public void bar() {
// bar's code
cooldown(2000);
}
}
You are very close already ... minor change ...
private synchronized void cooldown(long ms) throws InterruptedException {
Thead.sleep(ms);
}
Alternatively, you could handle the InterruptedException in the cooldown method itself.
Also, note that your code could actually execute foo, bar, and foobar in any order. The cooldown will slow down the foo or the bar (depending on which gets executed first).
I'd love to use a construct like Thread.sleep(), but in this case,
that would have the undesirable effects of forcing the calling thread
to sleep and not preventing any other thread from making method calls
on A.
Your approach does what you want. Other threads ARE prevented from making method calls on A (if you have synchronized the methods - which you have).
I'm trying to implement a work queue in Java that limits the amount of work that can be taken at a time. In particular, it is trying to protect access to an external resource. My current approach is to use a Semaphore and a BlockingQueue so that I have something like this:
interface LimitingQueue<V> {
void put(Callable<V> work);
Callable<V> tryPoll();
}
It should behave like this:
#Test
public void workLimit() throws Exception {
final int workQueue = 2;
final LimitingQueue<Void> queue = new LimitingQueue<Void>(workQueue);
queue.put(new Work()); // Work is a Callable<Void> that just returns null.
queue.put(new Work());
// Verify that if we take out one piece of work, we don't get additional work.
Callable<Void> work = queue.tryPoll();
assertNotNull(work, "Queue should return work if none outstanding");
assertNull(queue.tryPoll(), "Queue should not return work if some outstanding");
// But we do after we complete the work.
work.call();
assertNotNull(queue.tryPoll(), "Queue should return work after outstanding work completed");
}
The implementation of tryPoll() uses Semaphore#tryAcquire and, if successful, creates an anonymous Callable that wraps the Semaphore#release call in a try/finally block around the call to work.call().
This works, but is somewhat unsatisfying in that if the user of this class puts work that is of some specific class that implements Callable, the user does not get access to that class back when looking at the result of tryPoll. Notably, tryPoll() returns a Callable<Void>, not a Work.
Is there a way to achieve what the work limitation effect while giving the caller back a usable reference to the work object that was submitted? (It's fine to strengthen the type signature of LimitingQueue to be more like LimitingQueue<R, T extends Callable<R>>.) I can't think of a way to ensure that the semaphore is released after calling the work item without doing this kind of wrapping.
EDIT2 I have replaced what was here with a suggestion on how to implement what you're looking for. Let me know if you want some of the old info back and I can restore it.
public class MyQueue<T> {
private Semaphore semaphore;
public void put(Work<T> w) {
w.setQueue(this);
}
public Work<T> tryPoll() {
return null;
}
public abstract static class Work<T> implements Callable<T> {
private MyQueue<T> queue;
private void setQueue(MyQueue<T> queue) {
if(queue != null) {
throw new IllegalStateException("Cannot add a Work object to multiple Queues!");
}
this.queue = queue;
}
#Override
public final T call() throws Exception {
try {
return callImpl();
} finally {
queue.semaphore.release();
}
}
protected abstract T callImpl() throws Exception;
}
}
Then use it like thus:
public class Test {
public static void main(String[] args) {
MyQueue<Integer> queue = new MyQueue<Integer>();
MyQueue.Work<Integer> work = new MyQueue.Work<Integer>() {
#Override
protected Integer callImpl() {
return 5;
}
};
queue.put(work);
MyQueue.Work<Integer> sameWork = queue.tryPoll();
}
}
Sounds to me like you should just use the builtin ExecutorService. Use Executors#newCachedThreadPool to get a pool, then submit Callable jobs which return back a Future.
I have some code that I want to have some one time initialisation performed. But this code doesn't have a definite lifecycle, so my logic can be potentially invoked by multiple threads before my initialisation is done. So, I want to basically ensure that my logic code "waits" until initialisation is done.
This is my first cut.
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
synchronized(initialised) {
initStuff();
initialised.getAndSet(true);
initialised.notifyAll();
}
}
public void doStuff() {
synchronized(initialised) {
if (!initialised.get()) {
try {
initialised.wait();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
}
}
doOtherStuff();
}
}
I basically want to make sure this is going to do what I think it's going to do -- block doStuff until the initialised is true, and that I'm not missing a race condition where doStuff might get stuck on a Object.wait() that will never arrive.
Edit:
I have no control over the threads. And I want to be able to control when all of the initialisation is done, which is why doStuff() can't call initialise().
I used an AtomicBoolean as it was a combination of a value holder, and an object I could synchronize. I could have also simply had a "public static final Object lock = new Object();" and a simple boolean flag. AtomicBoolean conveniently gave me both. A Boolean can not be modified.
The CountDownLatch is exactly what I was looking for. I also considered using a Sempahore with 0 permits. But the CountDownLatch is perfect for just this task.
That's a strange mix of library and built-in concurrency controls. Something like this is much cleaner:
public class MyClass {
private static final CountDownLatch latch = new CountDownLatch(1);
public void initialise() {
initStuff();
latch.countDown();
}
public void doStuff() {
try {
latch.await();
} catch (InterruptedException ex) {
throw new RuntimeException("Uh oh!", ex);
}
doOtherStuff();
}
}
A synchronized block will automatically block other threads. Just use a simple lock object + status variable:
public class MyClass {
private static boolean initialised;
private static final Object lockObject = new Object();
public void initialise() {
synchronized (lockObject) {
if (!initialised) {
initStuff();
initialised = true;
}
}
}
public void doStuff() {
initialise();
doOtherStuff();
}
}
The best may be to use a static initializer (as mentioned by SB):
public class MyClass {
public static void doInitialize() {
...
}
public void doStuff() {
doOtherStuff();
}
static {
doInitialize();
}
}
This will get executed once before any other code is allowed to be called. If you will always have to initialize anytime the class is used then there is no performance hit as the class will not be loaded until it is used. See the answers to this question for more details.
It this is right at startup, why not wait to start the other threads until the initialization is complete?
Also, you can do a thread-synchronized IsComplete boolean that is set to false until it is set to true by the initialization routine.
You're using AtomicBoolean always from inside a synchronized block. There's not much point to that since only one thread can access it. Atomic variables are intended for use in lock-free solutions - you can get and set the value as an uninterruptable unit.
I guess you are looking for a lock free solution once the intiialization has happened:
public class MyClass {
private static final AtomicBoolean initialised = new AtomicBoolean(false);
public void initialise() {
if (!intialized.get())
{
synchornized (this)
{
if (!initialized.getAndSet(true))
doInitialize();
}
}
}
public void doStuff() {
initialize();
doOtherStuff();
}
You could also do this with a simple volatile boolean which is actually a little more efficient than an AtomicBoolean.