How to acquire multiple locks without ordering constraints in Java? - java

So I have code similar to this
synchronized(objectOne){ do stuff }
synchronized(objectTwo){ do stuff }
The problem with this is the program will wait for the lock on objectOne, even if the lock for objectTwo is available. What I'm trying to do is say: try to lock both objectOne and objectTwo, and whichever lock you get first do the stuff for that lock. I've come up with a solution but I think it's rather hacky and I'm wondering if anybody has any better ideas.
Here's my idea: Start 2 threads, each one waiting on a lock and then the main thread will wait on a CountDownLatch. So you end up with something like this:
CountDownLatch latch = new CountDownLatch(2);
new Thread(new Runnable(){
public void run(){
synchronized(objectOne) { do stuff }
latch.countDown();
}).start();
new Thread(new Runnable(){
public void run(){
synchronized(objectTwo) { do stuff }
latch.countDown();
}).start();
latch.await();

I think you should use Lock which provides you with the method boolean tryLock().
Returns:
true if the lock was acquired and false otherwise
Proceed with do stuff when you have at least one of the locks.

You might want to have 2 queues of jobs, 2 threads each polling a queue and execute the jobs.
For jobs related to objectOne, you put it in queue#1; jobs related to objectTwo in queue#2.
worker1.queue.put( new Runnable(){ public void run() { do stuff } } );
worker2.queue.put( new Runnable(){ public void run() { do stuff } } );
----
class Worker extends Thread
BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>();
public void run()
while(true)
queue.take().run();

Depending on the amount of stuff it could be more overhead to spin off multiple threads to do stuff. It might just be best to do stuff in a single thread if stuff is a fast enough operation. You will have to time it to know.

I kind of like your hack, at least if it's a one-off situation. That said...
If you're doing this sort of thing a lot and want something "less hacky", I'd suggest ExecutorService#invokeAll(). This takes a list of Callables, executes them on a thread pool and blocks until they're all done.
Sketch:
ExecutorService es = Executors.newCachedThreadPool(); // for example...
List<Future<Void>> results = es.invokeAll(new ArrayList {{
add(new Callable<Void> {
public Void call() { synchronized(objectOne) { do stuff } }
});
add(new Callable<Void> {
public Void call() { synchronized(objectTwo) { do stuff } }
});
}});
// both Callables are done when you get here
This obviously assumes that it's ok to call these methods from different threads at this point in your app. If for some reason you need to call both from the same thread, I think you're doomed to use tryLock and busy-wait as discussed in Bhesh Gurung's answer.

Related

Using thread for parallel processing in java

I need few of the functions in my program to run simultaneously. These processes returns records. But, the output of one is the input to the other. In such a case, if at a point of time function A takes some time to output some record to the function B, I need to the function B to wait till function A provides some records as input for this process. Can I achieve this simply by using the thread functionalities such as wait, join, etc.. Or Is there any other ways to achieve the same functionality.
Edited:
As per the below mentioned suggestions, If I use the producer-consumer algorithm with BlockingQueue,ExecutorService, Future and CountDownLatch, Can I achieve every functionalities I requested?
As mentioned above you can use blocking queue with producer consumer
OR
You can use countdown latch of the java concurrency to solve your problem.
How CountDownLatch works?
CountDownLatch.java class defines one constructor inside:
//Constructs a CountDownLatch initialized with the given count.
public void CountDownLatch(int count) {...}
This count is essentially the number of threads, for which latch should wait. This value can be set only once, and CountDownLatch provides no other mechanism to reset this count.
The first interaction with CountDownLatch is with main thread which is goind to wait for other threads. This main thread must call, CountDownLatch.await() method immediately after starting other threads. The execution will stop on await() method till the time, other threads complete their execution.
Other N threads must have reference of latch object, because they will need to notify the CountDownLatch object that they have completed their task. This notification is done by method : CountDownLatch.countDown(); Each invocation of method decreases the initial count set in constructor, by 1. So, when all N threads have call this method, count reaches to zero, and main thread is allowed to resume its execution past await() method.
Below is a simple example. After the Decrementer has called countDown() 3 times on the
CountDownLatch, the waiting Waiter is released from the await() call.
CountDownLatch latch = new CountDownLatch(3);
Waiter waiter = new Waiter(latch);
Decrementer decrementer = new Decrementer(latch);
new Thread(waiter) .start();
new Thread(decrementer).start();
Thread.sleep(4000);
public class Waiter implements Runnable{
CountDownLatch latch = null;
public Waiter(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Waiter Released");
}
}
public class Decrementer implements Runnable {
CountDownLatch latch = null;
public Decrementer(CountDownLatch latch) {
this.latch = latch;
}
public void run() {
try {
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
Thread.sleep(1000);
this.latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
In your case you can use callable to create thread instead of runnable as you need to get the retrun value from one thread and have to pass that value to second thread.
In most cases you do not need to use wait etc. All you need to do is choose a good safe structure to use to communicate between your threads,
In this specific case I would suggest one of the concurrent queuue implementations, perhaps a BlockingQueue such as ArrayBlockingQueue.
Java's Fork and Join looks suitable for the usecase specified in your Question.
See http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html
Have a look at BlockingQueue classes and producer/consumer patterns.
The first thread is getting the work unit from an input blocking queue and putting its output to an output blocking queue (with size restrictions).
The second thread is doing the using this output queue as an input.
With this method you can also easialy adjust the number of threads.
Ensure the the work load per work unit is not to small.
This is similar to producer-consumer problem. You can use Java's BlockingQueue.
The process A will enqueue its results and the process B will wait until A's output is ready in the queue. When output of A is available, then B can read and consume it.
This looks like the consumer-producer-problem. As suggested by others you can use a BlockingQueue. Here is an example for how to use it:
public static void main(final String[] args) {
final ExecutorService producer = Executors.newSingleThreadExecutor();
final ExecutorService consumer = Executors.newSingleThreadExecutor();
final BlockingQueue<Integer> workpieces = new LinkedBlockingQueue<>();
producer.submit(new Runnable() {
#Override
public void run() {
final Random rand = new Random();
for (;;) {
try {
workpieces.put(rand.nextInt());
Thread.sleep(1000);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
});
consumer.submit(new Runnable() {
#Override
public void run() {
for (;;) {
try {
System.out.println("Got " + workpieces.take());
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
}
}
});
}
It generates a random number every second in the producer-thread which is printed by the consumer-thread.
You can use BlockingQueue between producer and consumer threads. The producer will keep on adding results to queue if it is not full, concurrently the consumer thread can process pending messages from queue.

What are the thread command alternatives in Java?

I am dealing with threads and I want to run this code whenever I open Cal_JInternalFrame. It runs the fist time, but whenever I reopen the frame, it doesn't run again. I use t1.interrupted() at exit time of the whole application. The code is:
Thread t1 = new Thread( new Runnable() {
#Override
public void run() {
while ( !t1.isInterrupted() ) {
// ......... Oil Calculation Thread ...
int price = (Integer.parseInt(jLabel22.getText()));
int qty = (Integer)jSpinner8.getValue();
int totalOil =qty * price;
jTextField19.setText(String.valueOf(totalOil));
}
}
});
t1.start() is in the constructor of the main frame.
The thread primitive methods destroy(), stop(), resume(), and suspend() have been deprecated, so I can't use those. How can I stop and resume a thread now? And if my thread t1 is interrupted, how can it be resumed or run again?
Threads cannot be re-used. For tasks that require to be executed on a separate thread at different times, use a single thread executor.
It seems like you need a worker thread. Since standard threads are not reusable without extra work, we use worker threads to manage tasks that should be executed multiple times.
ExecutorService executors = Executors.newSingleThreadExecutor();
With this, you can reuse a single thread to execute code multiple times. It also allows you to make asynchronous callbacks using Future like this:
class Demo {
static ExecutorService executor = Executors.newSingleThreadExecutor();
public static void main(String[] args) {
Future<String> result = executor.submit(new Callable<String>() {
public String call() {
//do something
return "Task Complete";
}
});
try {
System.out.println(result.get()); //get() blocks until call() returns with its value
}catch(Exception e) {
e.printStackTrace();
}
}
}
You can now re-use executor for the task that you want. It accepts Runnable through it's execute(Runnable) method.
I see you're using Swing. Post all swing code to the Event Dispatch Thread using EventQueue.invokeLater(Runnable). getText() and setText() should be called on the Event Dispatch Thread to avoid inconsistancies.
How can I stop and resume a thread now?
You can't. Instead, you need to make your thread stop and resume itself. For example:
private boolean wake;
public synchronized void wakeup() {
this.wake = true;
this.notify();
}
public void run() {
while ( !t1.isInterrupted() ) {
// do stuff ...
wake = false;
synchronized (this) {
while (!wake) {
try {
this.wait();
} catch (InterruptedException ex) {
t1.interrupt(); // reset the interrupted flag
}
}
}
}
}
When some other thread wants to get this one to do something, the calls the wakeup() method on the extended runnable object.
And if my thread t1 is interrupted, how can it be resumed or run again?
As you have written it, No. Once the thread returns from the run() method call, it cannot be restarted. You would need to create and start a brand new Thread.
However, what you are trying to do is unsafe. As #Erwin points out, it is not safe for the t1 thread to be calling methods on Swing objects such as jTextField19. You should only call methods on Swing objects from the Swing event dispatching thread.
Reference:
Concurrency in Swing

how to implement timeout in java to see whether the response come

I have a two functions, one is the master and the other is the slave. Via master function I'm trying to learn behaviour of the other function. But I should do whatever calculation is a setted time interval. In this part, how can I set a timer, which is marked a boolean variable if timeout occur, and learn whether timeout occurs ?
func1 -----send message------> func2
start timer
if timeout occur, do something else
You can execute func2 in another Thread and let your original Thread join() with a specified timeout.
Of course you will need to take care of proper synchronization.
Simple example (left out InteruptedException handling)
void func1(){
Thread slave = new Thread(new Runnable(){
public void run(){
func2();
}
});
slave.start();
slave.join(100); // waits 100 milliseconds for slave to complete
if(!slave.isAlive()){
//slave completed its task
}else{
//slave not done yet, do something else
somethingElse();
}
}
Use the concurrent constructs in the JDK. In this case an ExecutorService and a CountDownLatch is a perfect match:
ExecutorService executor = Executors.newCachedThreadPool();
final CountDownLatch ready = new CountDownLatch(1);
executor.execute(new Runnable() {
#Override
public void run() {
// do something here
System.out.println("working ...");
ready.countDown();
}
});
boolean timeout = !ready.await(1, TimeUnit.MILLISECONDS);
if (timeout) {
doSomethingElse();
}

How can I create a new thread only if no other threads are currently open?

This code creates and starts a thread:
new Thread() {
#Override
public void run() {
try { player.play(); }
catch ( Exception e ) { System.out.println(e); }
}
}.start();
I'd like to modify this code so that the thread only starts if there are no other threads open at the time! If there are I'd like to close them, and start this one.
You can create an ExecutorService that only allows a single thread with the Executors.newSingleThreadExecutor method. Once you get the single thread executor, you can call execute with a Runnable parameter:
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable() { public void run() { /* do something */ } });
My preferred method would be putting a synchronized keyword on the play method
synchronized play()
synchronized methods will lock the function so only one thread will be allowed to execute them at a time.
Here's some more info
https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
you could create a static data member for the class(where threading takes place) which is incremented each time an object of that class is called,read that and u get the number of threads started

Wait until any of Future<T> is done

I have few asynchronous tasks running and I need to wait until at least one of them is finished (in the future probably I'll need to wait util M out of N tasks are finished).
Currently they are presented as Future, so I need something like
/**
* Blocks current thread until one of specified futures is done and returns it.
*/
public static <T> Future<T> waitForAny(Collection<Future<T>> futures)
throws AllFuturesFailedException
Is there anything like this? Or anything similar, not necessary for Future. Currently I loop through collection of futures, check if one is finished, then sleep for some time and check again. This looks like not the best solution, because if I sleep for long period then unwanted delay is added, if I sleep for short period then it can affect performance.
I could try using
new CountDownLatch(1)
and decrease countdown when task is complete and do
countdown.await()
, but I found it possible only if I control Future creation. It is possible, but requires system redesign, because currently logic of tasks creation (sending Callable to ExecutorService) is separated from decision to wait for which Future. I could also override
<T> RunnableFuture<T> AbstractExecutorService.newTaskFor(Callable<T> callable)
and create custom implementation of RunnableFuture with ability to attach listener to be notified when task is finished, then attach such listener to needed tasks and use CountDownLatch, but that means I have to override newTaskFor for every ExecutorService I use - and potentially there will be implementation which do not extend AbstractExecutorService. I could also try wrapping given ExecutorService for same purpose, but then I have to decorate all methods producing Futures.
All these solutions may work but seem very unnatural. It looks like I'm missing something simple, like
WaitHandle.WaitAny(WaitHandle[] waitHandles)
in c#. Are there any well known solutions for such kind of problem?
UPDATE:
Originally I did not have access to Future creation at all, so there were no elegant solution. After redesigning system I got access to Future creation and was able to add countDownLatch.countdown() to execution process, then I can countDownLatch.await() and everything works fine.
Thanks for other answers, I did not know about ExecutorCompletionService and it indeed can be helpful in similar tasks, but in this particular case it could not be used because some Futures are created without any executor - actual task is sent to another server via network, completes remotely and completion notification is received.
simple, check out ExecutorCompletionService.
ExecutorService.invokeAny
Why not just create a results queue and wait on the queue? Or more simply, use a CompletionService since that's what it is: an ExecutorService + result queue.
This is actually pretty easy with wait() and notifyAll().
First, define a lock object. (You can use any class for this, but I like to be explicit):
package com.javadude.sample;
public class Lock {}
Next, define your worker thread. He must notify that lock object when he's finished with his processing. Note that the notify must be in a synchronized block locking on the lock object.
package com.javadude.sample;
public class Worker extends Thread {
private Lock lock_;
private long timeToSleep_;
private String name_;
public Worker(Lock lock, String name, long timeToSleep) {
lock_ = lock;
timeToSleep_ = timeToSleep;
name_ = name;
}
#Override
public void run() {
// do real work -- using a sleep here to simulate work
try {
sleep(timeToSleep_);
} catch (InterruptedException e) {
interrupt();
}
System.out.println(name_ + " is done... notifying");
// notify whoever is waiting, in this case, the client
synchronized (lock_) {
lock_.notify();
}
}
}
Finally, you can write your client:
package com.javadude.sample;
public class Client {
public static void main(String[] args) {
Lock lock = new Lock();
Worker worker1 = new Worker(lock, "worker1", 15000);
Worker worker2 = new Worker(lock, "worker2", 10000);
Worker worker3 = new Worker(lock, "worker3", 5000);
Worker worker4 = new Worker(lock, "worker4", 20000);
boolean started = false;
int numNotifies = 0;
while (true) {
synchronized (lock) {
try {
if (!started) {
// need to do the start here so we grab the lock, just
// in case one of the threads is fast -- if we had done the
// starts outside the synchronized block, a fast thread could
// get to its notification *before* the client is waiting for it
worker1.start();
worker2.start();
worker3.start();
worker4.start();
started = true;
}
lock.wait();
} catch (InterruptedException e) {
break;
}
numNotifies++;
if (numNotifies == 4) {
break;
}
System.out.println("Notified!");
}
}
System.out.println("Everyone has notified me... I'm done");
}
}
As far as I know, Java has no analogous structure to the WaitHandle.WaitAny method.
It seems to me that this could be achieved through a "WaitableFuture" decorator:
public WaitableFuture<T>
extends Future<T>
{
private CountDownLatch countDownLatch;
WaitableFuture(CountDownLatch countDownLatch)
{
super();
this.countDownLatch = countDownLatch;
}
void doTask()
{
super.doTask();
this.countDownLatch.countDown();
}
}
Though this would only work if it can be inserted before the execution code, since otherwise the execution code would not have the new doTask() method. But I really see no way of doing this without polling if you cannot somehow gain control of the Future object before execution.
Or if the future always runs in its own thread, and you can somehow get that thread. Then you could spawn a new thread to join each other thread, then handle the waiting mechanism after the join returns... This would be really ugly and would induce a lot of overhead though. And if some Future objects don't finish, you could have a lot of blocked threads depending on dead threads. If you're not careful, this could leak memory and system resources.
/**
* Extremely ugly way of implementing WaitHandle.WaitAny for Thread.Join().
*/
public static joinAny(Collection<Thread> threads, int numberToWaitFor)
{
CountDownLatch countDownLatch = new CountDownLatch(numberToWaitFor);
foreach(Thread thread in threads)
{
(new Thread(new JoinThreadHelper(thread, countDownLatch))).start();
}
countDownLatch.await();
}
class JoinThreadHelper
implements Runnable
{
Thread thread;
CountDownLatch countDownLatch;
JoinThreadHelper(Thread thread, CountDownLatch countDownLatch)
{
this.thread = thread;
this.countDownLatch = countDownLatch;
}
void run()
{
this.thread.join();
this.countDownLatch.countDown();
}
}
If you can use CompletableFutures instead then there is CompletableFuture.anyOf that does what you want, just call join on the result:
CompletableFuture.anyOf(futures).join()
You can use CompletableFutures with executors by calling the CompletableFuture.supplyAsync or runAsync methods.
Since you don't care which one finishes, why not just have a single WaitHandle for all threads and wait on that? Whichever one finishes first can set the handle.
See this option:
public class WaitForAnyRedux {
private static final int POOL_SIZE = 10;
public static <T> T waitForAny(Collection<T> collection) throws InterruptedException, ExecutionException {
List<Callable<T>> callables = new ArrayList<Callable<T>>();
for (final T t : collection) {
Callable<T> callable = Executors.callable(new Thread() {
#Override
public void run() {
synchronized (t) {
try {
t.wait();
} catch (InterruptedException e) {
}
}
}
}, t);
callables.add(callable);
}
BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(POOL_SIZE);
ExecutorService executorService = new ThreadPoolExecutor(POOL_SIZE, POOL_SIZE, 0, TimeUnit.SECONDS, queue);
return executorService.invokeAny(callables);
}
static public void main(String[] args) throws InterruptedException, ExecutionException {
final List<Integer> integers = new ArrayList<Integer>();
for (int i = 0; i < POOL_SIZE; i++) {
integers.add(i);
}
(new Thread() {
public void run() {
Integer notified = null;
try {
notified = waitForAny(integers);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println("notified=" + notified);
}
}).start();
synchronized (integers) {
integers.wait(3000);
}
Integer randomInt = integers.get((new Random()).nextInt(POOL_SIZE));
System.out.println("Waking up " + randomInt);
synchronized (randomInt) {
randomInt.notify();
}
}
}

Categories

Resources