java: wait until another thread performs a statement n times - java

what is the best way to stop a thread and wait for a statement (or a method) to be executed a certain number of times by another thread?
I was thinking about something like this (let "number" be an int):
number = 5;
while (number > 0) {
synchronized(number) { number.wait(); }
}
...
synchronized(number) {
number--;
number.notify();
}
Obviously this wouldn't work, first of all because it seems you can't wait() on a int type. Furthermore, all other solutions that come to my java-naive mind are really complicated for such a simple task. Any suggestions? (Thanks!)

Sounds like you're looking for CountDownLatch.
CountDownLatch latch = new CountDownLatch(5);
...
latch.await(); // Possibly put timeout
// Other thread... in a loop
latch.countDown(); // When this has executed 5 times, first thread will unblock
A Semaphore would also work:
Semaphore semaphore = new Semaphore(0);
...
semaphore.acquire(5);
// Other thread... in a loop
semaphore.release(); // When this has executed 5 times, first thread will unblock

You might find something like a CountDownLatch useful.

Related

Facing Issues in Multithreading

I have written a code where it will launch the fixed number of threads from the main class. Below function is just a part of it . All threads will come to this method. I have given thread names like USER1, USER2 etc.
My requirement is that in this method after driver=WebDriver....... statement all of my threads should wait until they all get the driver. I know we can join . But unable to implement here . Can someone please guide
private void testSuitLogin(String driverType){
try{
System.out.println(Thread.currentThread().getName()+" Start Time "+System.currentTimeMillis());
driver = WebDriverFactory.getDriver(driverType);
System.out.println(Thread.currentThread().getName()+" End Time "+System.currentTimeMillis());
homePage();
googleSignIn();
driver.quit();
}
catch(Exception e){
if(driver==null)
{
totalNumberOfUsers--;
return ;
}
}
}
You can use the CountDownLatch. Create a CountDownLatch with a fixed number of thread value and call countdown() after you get the instance of the WebDriver and then call await() to wait until all the threads arrive there.
CountDownLatch countDownLatch = new CountDownLatch(fixedNumber);
private void testSuitLogin(String driverType){
try{
System.out.println(Thread.currentThread().getName()+" Start Time "+System.currentTimeMillis());
driver = WebDriverFactory.getDriver(driverType);
countDownLatch.countDown(); // decreases the value of latch by 1 in each call.
countDownLatch.await(); //It will wait until value of the latch reaches zero.
System.out.println(Thread.currentThread().getName()+" End Time "+System.currentTimeMillis());
homePage();
googleSignIn();
driver.quit();
}
catch(Exception e){
if(driver==null)
{
countDownLatch.countDown();
totalNumberOfUsers--;
return ;
}
}
}
First: If all wait for all to get the driver, then you have a problem when one fails to get the driver.
In order to have all wait for each other (I don't think I have actually ever done that, but here is a suggestion). Since you know the number of threads, you can make something like:
Thread gets driver
Thread calls a synchronized method (only 1 thread can run it at a time) that decrements a counter by 1 (initialized to the number of threads).
Thread yields.
Thread runs again, calls a method that checks if the counter has reached 0.
A: Counter is not 0 yet, thread yields.
B: Counter is 0, thread continues its work.

Ideas to avoid doing a trick on CyclicBarrier

I was running some tests with parallel processing and made a program that given a matrix of integers re-calcutes each position's value based on the neighbours.
I needed a copy of the matrix so the values wouldn't be overriden and used a CyclicBarrier to merge the results once the partial problems were solved:
CyclicBarrier cyclic_barrier = new CyclicBarrier(n_tasks + 1, new Runnable() {
public void run() {
ParallelProcess.mergeResult();
}
});
ParallelProcess p = new ParallelProcess(cyclic_barrier, n_rows, r_cols); // init
Each task is assigned a portion of the matrix: I'm splitting it in equals pieces by rows. But it might happen that the divisions are not exact so there would be a small piece corresponding to the lasts row that wouldn't be submitted to the thread pool.
Example: if I have 16 rows and n_tasks = 4 no problem, all 4 will be submitted to the pool. But if I had 18 instead, the first 16 ones will be submitted, but not the last two ones.
So I'm forcing a submit if this case happens. Well, I'm not submitting actually, because I am using a fixed thread pool that I created like this ExecutorService e = Executors.newFixedThreadPool(n_tasks). Since all the slots in the pool are occupied and the threads are blocked by the barrier (mybarrier.await() is called in the run method) I couldn't submit it to the pool, so I just used Thread.start().
Let's go to the point. Since I need to take into consideration for the CyclicBarrier the possibility of that chunk remaining, the number of parties must be incremented by 1.
But if this case didn't happen, I would be one party short to trigger the barrier.
What's my solution?:
if (lower_limit != n_rows) { // the remaining chunk to be processed
Thread t = new Thread(new ParallelProcess(lower_limit, n_rows));
t.start();
t.join();
}
else {
cyclic_barrier.await();
}
I feel like I am cheating when using the cyclic_barrier.await() trick to raise the barrier by force.
Is there any other way I could approach this problem so I didn't have to do what I'm doing?
Though this doesn't answer your question about CyclicBarriers, can I recommend using a Phaser? This does have the ability to include the number of parties, and it also allows you to run the mergeResult when a phase is tripped.
So, before you execute an async calculation, simply register. Then inside that calculation have the thread arrive on the phaser. When all threads have arrived, it will advance the phase and can invoke an overriden method onAdvance.
The submission:
ParallelProcess process = new ParallelProcess(lower_limit, n_rows));
phaser.register();
executor.submit(process);
The processor
public void run(){
//do stuff
phaser.arrive();
}
The phaser
Phaser phaser = new Phaser(){
protected boolean onAdvance(int phase, int registeredParties) {
ParallelProcess.mergeResult();
return true;
}
}

Get values from an infinite loop

I have 5 threads running in an infinite loop. I need to fetch the final value after all 5 threads end every time. How can I do this?
while(true){
new Class1(1,10).start();
new Class1(11,20).start();
new Class1(21,30).start();
new Class1(31,40).start();
new Class1(41,50).start();
}
I need to determine the end of these 5 threads and pick one particular value updated in all the threads. How can I do this?
Your code here is going to start 5 new threads every single time around the loop and keep looping constantly. Are you absolutely sure that's what you want?
Just use a CountDownLatch http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/CountDownLatch.html
Initialize the latch at 5. Each thread counts the latch down once when it exits.
The main thread waits for the latch to hit 0 then does its processing and exits.
Do not loop creating threads!
while(true){
List<Class1> x = Arrays.asList( new Class1(1,10), new Class1(11,20), new Class1(21,30), new Class1(31,40), Class1(41,50));
for (Class1 t: x) {
x.start();
}
for (Class1 t: x) {
x.join();
}
}

Mutual exclusion code

I'm trying to convert this code to java and using thread to implement it
turn = 0 // shared control variable
while (turn != i);
// CS
turn = (turn + 1) % n;
I'm really tried hard to reach to right code but I failed this is my code
/*
* Mutual exclusion using thread
*/
class gV{
int turn=0;
}
class newThread extends Thread{
static int i;
int n=10;
newThread(gV obj){
this.i=obj.turn;
start();
}
public void run(){
while(obj.turn!=i&&obj.turn<n);
criticalSection(i);
obj.turn=(obj.turn+1);
i++;
}
public void criticalSection(int numOfProcess){
System.out.println("Process " + numOfProcess + " done!!");
}
}
class MutualExclusion{
public static void main(String args[]){
gV obj = new gV();
new newThread(obj);
}
}
I know my code has some mistakes. Thank you for the help!
Use an AtomicInteger.
Atomic means that any operation on it will fully complete before any other thread can see the result. Meaning that you won't have two simultaneous operations 'clobber' it. For example, imagine if you had a non atomic integer and two threads attempted to increment it simultaneously - say it had value 1, they both read it as 1 and attempt to set it to 2. They both incremented it once - but instead of it becoming 3, it became 2! AtomicInteger solves this problem by giving you IncrementAndGet, which guarantees no other thread can access the AtomicInteger's value before the increment completes.
In particular, use these methods:
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#get()
http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/atomic/AtomicInteger.html#incrementAndGet()
You might notice that this increments it, but it doesn't take it modulo n. Well, you can take it modulo n whenever you read its value, you don't need it to be stored that way.
EDIT: By the way, doing something like this:
while (turn != i);
is called busy-waiting, and it's a bad idea because it means that CPU usage will be 100%, checking the variable hundreds of thousands of times per second. In this kind of scenario, instead of making each thread check as often as possible, you want to have threads wait and be notifyed by another thread when it is that thread's turn to continue execution.
I believe in Java that using lock and synchronized to implement mutual exclusion will also give you this property, e.g. if you try to lock on something or enter a synchronized block but it is already in use then the thread goes to sleep and is woken up when it is its turn. So, you can look into this as well.

Java Delay/Wait

How do I delay a while loop to 1 second intervals without slowing down the entire code / computer it's running on to the one second delay (just the one little loop).
Thread.sleep(1000); // do nothing for 1000 miliseconds (1 second)
It seems your loop runs on Main thread and if you do sleep on that thread it will pause the app (since there is only one thread which has been paused), to overcome this you can put this code in new Thread that runs parallely
try{
Thread.sleep(1000);
}catch(InterruptedException ex){
//do stuff
}
My simple ways to delay a loop.
I already put the codes here after failing to follow the stackoverflow's standards.
//1st way: Thread.sleep : Less efficient compared to 2nd
try {
while (true) {//Or any Loops
//Do Something
Thread.sleep(sleeptime);//Sample: Thread.sleep(1000); 1 second sleep
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//================================== Thread.sleep
//2nd way: Object lock waiting = Most efficient due to Object level Sync.
Object obj = new Object();
try {
synchronized (obj) {
while (true) {//Or any Loops
//Do Something
obj.wait(sleeptime);//Sample obj.wait(1000); 1 second sleep
}
}
} catch (InterruptedException ex) {
//SomeFishCatching
}
//=============================== Object lock waiting
//3rd way: Loop waiting = less efficient but most accurate than the two.
long expectedtime = System.currentTimeMillis();
while (true) {//Or any Loops
while(System.currentTimeMillis() < expectedtime){
//Empty Loop
}
expectedtime += sleeptime;//Sample expectedtime += 1000; 1 second sleep
//Do Something
}
//===================================== Loop waiting
As Jigar has indicated you can use another Thread to do work which can operate, sleep etc independently of other Threads. The java.util.Timer class might help you as well since it can perform periodic tasks for you without you having to get into multithreaded programming.

Categories

Resources