Threads wait for each other after each iteration - java

I would like for thread A to iterate once through the for loop, wait for thread B to loop once through the for loop and wait for thread C to loop once through the for loop. And then all over again. I tried to use wait() and notify() but I got nowhere. How could one solve the problem?
public class Test extends Thread {
static int counter=0;
synchronized public void run() {
for(int i=0; i<4; i++) {
System.out.println(Thread.currentThread().getName()+" "+counter++);
}
}
public static void main(String[] args) throws InterruptedException {
Test t1 = new Test();
Test t2 = new Test();
Test t3 = new Test();
t1.setName("A");
t2.setName("B");
t3.setName("C");
t1.start();
t2.start();
t3.start();
}
}
It should print the following to the console:
A 0
B 1
C 2
A 3
B 4
C 5
A 6
B 7
C 8
A 9
B 10
C 11
But using the code I get a random output like this:
A 0
A 3
A 4
A 5
C 2
C 6
C 7
B 1
C 8
B 9
B 10
B 11

Since you are making instance method syncronized it will try to obtain monitor of current instance and as all 3 threads are different instance all obtain and release monitor independently. You should probably consider using join() to wait for other threads.
You can do something like -
public class Test extends Thread {
static int counter=0;
Test lockTest;
public Test(){}
public Test(Test t) {
this.lockTest = t;
}
public void run() {
for(int i=0; i<4; i++) {
System.out.println(Thread.currentThread().getName()+" "+counter++);
}
if(lockTest != null)
lockTest.join(); //wait for other thread
}
public static void main(String[] args) throws InterruptedException {
Test t1 = new Test(null);
Test t2 = new Test(t1);
Test t3 = new Test(t2);
t1.setName("A");
t2.setName("B");
t3.setName("C");
t1.start();
t2.start();
t3.start();
}
}

If you really need to solve it that way, you can use something like code below. But as other people mentioned it doesn't really make much sense to use threads in such case. I would suggest looking into Future class and ExecutorService.submit if you need to wait for results of computations from various tasks (or even better, guava ListenableFuture). Possibly CyclicBarrier, CountDownLatch, some kind of blocking queue... hard to say without knowing your real usecase, rather than mysterious code question.
public class Test extends Thread {
static int counter=0;
private Test previous;
public void run() {
for(int i=0; i<4; i++) {
synchronized(previous) {
try {
previous.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName()+" "+counter++);
synchronized(this) {
this.notify();
}
}
}
public static void main(String[] args) throws InterruptedException {
Test t1 = new Test();
Test t2 = new Test();
Test t3 = new Test();
t1.setName("A");
t2.setName("B");
t3.setName("C");
t1.previous = t3;
t2.previous = t1;
t3.previous = t2;
t1.start();
t2.start();
t3.start();
synchronized(t3) {
t3.notify();
}
}
}

If you want to loop endlessly between three Runnables in sequence, create the Runnables and feed them into a single threaded ThreadPoolExecutor or ExecutorService like so:
while (running)
{
ExecutorService threadPool = Executors.newSingleThreadExecutor(Executors.defaultThreadFactory());
threadPool.execute(new RunnableA());
threadPool.execute(new RunnableB());
threadPool.execute(new RunnableC());
threadPool.shutdown();
threadPool.awaitTermination();//put in a try/catch, omitted for brevity
}
That's what you really want. Note that the ExecutorService above has an unbounded queue so you'll have to limit the rate at which you submit tasks or use something like a ThreadPoolExecutor that lets you use bounded queues. Or you could just create a fresh ExecutorService with each loop, call shutdown() after each loop and then await termination at the end of the loop.
In case you were unaware of this, each of the RunnableA/B/C classes above should be soemthing like this:
public class RunnableA implements Runnable()
{
public void run()
{
//do stuff, ie, your loop
}
}
Of course there is always the option to just put all three loops in one method body, which has the advantage of being simpler.
public void doStuff()
{
//loopA
//loopB
//loopC
}

You want a fix type of output i.e. A X, B X, C X, A X, ... . And, you cannot fix the order of an execution of a threads.
And, the actual output you get is based on your syncronized keyword. Which fixes that first A will be printed then B and so on.
You cannot predict the execution of order of threads.

Related

Java Mutex | Thread : Current Thread is not owner [duplicate]

package pkg_1;
public class ExpOnWaitMethod extends Thread {
static Double x = new Double(20);
public static void main(String[] args) {
ExpOnWaitMethod T1 = new ExpOnWaitMethod();
ExpOnWaitMethod T2 = new ExpOnWaitMethod();
T1.start();
T2.start();
}
public void run() {
Mag mag = new Mag();
synchronized (x) {
try {
for (int i = 1; i < 10; i++) {
mag.nop(Thread.currentThread());
x = i * 2.0;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Mag {
char ccc = 'A';
public void nop(Thread thr) throws InterruptedException {
System.out.print(ccc + " ");
ccc++;
if (thr.getState().toString().equalsIgnoreCase("runnable"))
Thread.currentThread().wait();
//thr.notify();
}
}
You need to hold the lock on the object you want to wait on (you can only call it within a synchronized block).
Also, calling wait on a Thread is very unusual and probably not what you want.
I am not sure what you are trying to do, but could you be confusing wait with sleep?
If you want to wait for another thread to finish, that would be anotherThread.join().
Before you call wait on an object, you must acquire that object's lock:
synchronized(obj)
{
obj.wait();
}
Your code is calling wait on a Thread object without acquiring the lock first.
I assume this is just a simplified test case to show your problem, but note that you probably want to be calling wait on an object that is accessible from all threads, not on the Thread objects themselves.
Someone should cite the API contract for java.lang.Object.wait(), which explains this directly. If a method raises an exception, read the documentation.
When in doubt, read the contract. (Bill McNeal on NewsRadio always kept his in his jacket pocket, a good metaphor for the JavaDoc API.. see "Crazy Prepared" under NewsRadio and ponder the imponderable.)

Why do I have an issue with synchronization? [duplicate]

This question already has answers here:
synchronized block for an Integer object
(3 answers)
Closed 5 years ago.
Why doesn't variable named 'count' finally equal to 20000?
public class Main {
private Integer count = 0;
public void increment() {
synchronized (count) {
count++;
}
}
public static void main(String[] args) {
Main app = new Main();
app.doWork();
}
public void doWork() {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i=0; i<10000; i++) {
increment();
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i=0; i<10000; i++) {
increment();
}
}
});
t1.start();
t2.start();
System.out.println(count);
}
It seems that thread loses the variable but when does it happen? The same happens in a case of using AtomicInteger too.
P.S. could you please recommend a good course with exercises for learning multithreading in Java?)
Because start creates a new thread, and when you print the count you aren't sure the thread execution is finished.
t1.start();
t2.start();
System.out.println(count); // Here you don't know if t1 and t2 ended their execution
Join threads to wait for them to complete the task:
t1.start();
t2.start();
t1.join(); // wait for t1 to finish
t2.join(); // wait for t2 to finish
System.out.println(count); // 20000
Note: You'll have to handle InterruptedException on join calls.
You synchronize on count. But your code changes count. Different threads synchronizing on different objects don't guarantee atomicity.
Use a separate final monitor object to synchronize on.
See also #BackSlash 's answer for making sure you print the correct end result.
Edit
His answer comes down to : if you print the result without waiting for the threads to finish on your main thread you'll see some intermediate result, or possibly even 0.
So you need to call join(), which blocks until the thread finishes, on both threads before printing the end result.

Java Thread join() behavior

public class RunTest {
public static int counter = 0;
static class RunnerDec implements Runnable{
public void run(){
for(int i=0;i<5000; i++){
counter--;
}
}
}
static class RunnerInc implements Runnable{
public void run(){
for(int i=0;i<5000; i++){
counter++;
}
}
}
public static void main(String[] args) {
RunnerDec rd = new RunnerDec();
RunnerInc ri = new RunnerInc();
Thread t1 = new Thread(rd);
Thread t2 = new Thread(ri);
t1.start();
t2.start();
try{
t1.join(); // this will stop the main thread until t1 is done incrementing 5000 times
t2.join(); // this will stop the main thread until t2 is done incrementing 5000 times
}catch(Exception e){
e.printStackTrace();
}
System.out.println(counter);
}
}
I expect the result to be 0 every time alas this is not the case. The java doc says join() "waits for this thread to die". I feel like the main thread should wait for t1 to finish then wait for t2 to finish. That's not what is happening. Thanks for the clarity!!
It does wait for the threads to die. But your two threads concurrently update a shared variable without any synchronization, so you're seeing race conditions and visibility issues.
For example:
counter = 1000
thread 1 reads counter : 1000
thread 2 reads counter : 1000
thread 1 increments and writes counter: 1001
thread 2 decrements and writes counter: 999
Since ++ and -- are not atomic operations, the above thread interlacing example loses an increment.
The easiest way to fix them is to use an AtomicInteger rather than an int. To understand the crux of the problem, you'd better read Java Concurrency in Practice, or at the very least the Java concurrency tutorial.

How to slow a thread down in JAVA

I have this class in which I run a for loop 10 times. This class implements Runnable interface. Now in main() I create 2 threads. Now both will run loop till 10. But I want to check loop count for each thread. If t1 is past 7 then make it sleep 1 second so as to let t2 complete. But how to achieve this? Please see the code. I attempted but looks totally foolish. Just how to check the data of a thread ???
class SimpleJob implements Runnable {
int i;
public void run(){
for(i=0; i<10; i++){
System.out.println(Thread.currentThread().getName()+" Running ");
}
}
public int getCount(){
return i;
}
}
public class Threadings {
public static void main(String [] args){
SimpleJob sj = new SimpleJob();
Thread t1 = new Thread(sj);
Thread t2 = new Thread(sj);
t1.setName("T1");
t2.setName("T2");
t1.start();
try{
if(sj.getCount() > 8){ // I know this looks totally ridiculous, but then how to check variable i being incremented by each thread??
System.out.println("Here");
Thread.sleep(2000);
}
}catch(Exception e){
System.out.println(e);
}
t2.start();
}
}
Please help
You should use some synchronization object, and not rely on slowing down of threads. I strongly suggest you take a look at one of the classes at java.util.concurrent package. You can use for this CountdownLatch - thread 1 will await on it, and thread 2 will perform the countdown and release the lock, and let thread 1 continue (the release should be done at the end of thread 2 code).
I added a synchronized Block, which can be entered by one thread at a time. Both threads call and enter the method parallel. One thread will win the race and take the lock. After the first thread leaves the block it waits 2 seconds. In this time the second thread can iterate over the loop. I think this behaviour is wanted. If the second thread must not wait 2 seconds, too, you can set some boolean flag, that the first thread finished the block and use this flag in an if statement, which prevents the wait time of the second thread.
class SimpleJob implements Runnable {
int i;
public void run(){
synchronized (this) {
for(i=0; i<8; i++){
System.out.println(Thread.currentThread().getName()+" Running ");
}
}
try {
System.out.println("Here");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(i=0; i<2; i++){
System.out.println(Thread.currentThread().getName()+" Running ");
}
}
public int getCount(){
return i;
}
}
public class Threadings {
public static void main(String [] args){
SimpleJob sj = new SimpleJob();
Thread t1 = new Thread(sj);
Thread t2 = new Thread(sj);
t1.setName("T1");
t2.setName("T2");
t1.start();
t2.start();
}
}
If the goal is to run 2 Runnables in parallel (as Threads) and wait for them both to finish, you can, in increasing order of complexity/power:
Use Thread.join (as suggested by #Suraj Chandran but his reply seems to have been deleted)
Use a CountDownLatch (as also suggested by #zaske)
Use ExecutorService.invokeAll()
EDIT ADDED
First, I don't understand what the magic "if you are at 7 then wait for the other" logic is all about. But, to use Thread.join() from your main code, the code would look like
t1.start(); // Thread 1 starts running...
t2.start(); // Thread 2 starts running...
t1.join(); // wait for Thread 1 to finish
t2.join(); // wait for Thread 2 to finish
// from this point on Thread 1 and Thread 2 are completed...

Thread Synchronization - How to execute threads alternatively

I have been trying to solve a problem involving thread communication using wait() and notify(). Basically i have 2 threads T1 and T2 and i want them to be executed in the following order
T1 , T2, T1, T2 ..... How can i achieve that?
Actual Problem: There are 2 threads T1 - which prints odd numbers (say 1 - 100) and T2 - which prints even numbers (1 - 100). Now, the output should be 1, 2, 3, 4 , 5 , .... 100
You describe a Producer-Consumer pattern.
It's java implementations described in numerous java books including M.Grand "Patterns in Java. Volume I" and "Java 2: The Complete Reference" by Naughton and Schildt.
Basic idea: both threads should use 1 monitor (i.e. their code should be inside synchronized(monitor) {} blocks). You also need some flag variable which should indicate which of two threads should work at the moment.
When one of your threads is inside synchronized block it should check flag variable whether it's his turn to do the job. If yes, let it work and then change flag value and then notify all waiting threads. If no, then it should wait.
Look at the java.util.concurrent package, specifically the Exchanger
You're trying to parallelize a multistep process right? If so, see my answer here for an approach and some working code to do that. The answer involves an ExecutorService (or two) and one or more work queues.
For this approach, your processing needs to be able to fit into a Runnable, along with intermediate state information for the processing. You feed each step to the ExecutorService as a Runnable, which will add a second Runnable to perform the next step. This maintains the order of execution, but lets you effectively run as many threads as you wish in parallel.
:EDIT:
As another has suggested, the Exchanger library class can be used for this if you explicitly want to limit processing to 2 threads. I prefer the above approach because it maintains order of execution and allows you to use the modern 4-core (and 8-core) systems fully. It should also reduce synchronization a bit.
If T1 and T2 are 2 different implementations of the Runnable interface, with T1 being a thread that prints just odd numbers (1,3,...) and T2 being one that prints even number (1,2.....), this can be done by using the wait() and notify() methods on a shared monitor. The important thing is for each thread to check for a shared flag before printing its value. The below code works;
//The shared monitor
public class Mutex {
public static boolean oddFlag;
}
//The Thread that is supposed to print Odd numbers (assuming an upper limit of 99)
public class OddPrinter implements Runnable {
private Mutex mutex;
public OddPrinter(Mutex mutex) {
this.mutex = mutex;
}
public synchronized void run() {
System.out.println("Started Thread: OddPrinter");
int i;
for(i=1; i<100; i+=2 ) {
synchronized (mutex) {
while(!Mutex.oddFlag) {
try {
mutex.wait();
} catch (InterruptedException ie) {
Thread.currentThread().interrupted();
}
}
if(Mutex.oddFlag == true) {
System.out.println("Print from OddPrinter: "+i);
Mutex.oddFlag = false;
mutex.notify();
}
}
}
System.out.println("Finished Thread: OddPrinter: "+i);
}
}
//The Thread that is supposed to print Odd numbers (assuming an upper limit of 98)
public class EvenPrinter implements Runnable {
private Mutex mutex;
public EvenPrinter(Mutex mutex) {
this.mutex = mutex;
}
public synchronized void run() {
System.out.println("Started Thread: EvenPrinter");
int i;
for(i=2; i<100; i+=2) {
synchronized (mutex) {
while(Mutex.oddFlag) {
try {
mutex.wait();
} catch (InterruptedException ie) {
Thread.currentThread().interrupted();
}
}
if(!(Mutex.oddFlag == true)) {
System.out.println("Print from EvenPrinter: "+i);
Mutex.oddFlag = true;
mutex.notify();
}
}
}
System.out.println("Finished Thread: EvenPrinter: "+i);
}
}
//The test harness that executes the threads
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class NumberPrinterTest {
public static void main(String[] args) throws Exception{
ExecutorService es = Executors.newFixedThreadPool(2);
Mutex mutex = new Mutex();
OddPrinter op = new OddPrinter(mutex);
EvenPrinter ep = new EvenPrinter(mutex);
Mutex.oddFlag = true;
es.execute(op);
es.execute(ep);
if(null != es){
es.shutdown();
try {
es.awaitTermination(1, TimeUnit.MINUTES);
} catch (InterruptedException e) {
Thread.currentThread().interrupted();
}
}
}
}

Categories