Java Synchronized Threads not working as expected - java

The following code does not work as I expect it to:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
class Worker implements Runnable {
public void run() {
System.out.println("Started.");
process();
}
private Random random = new Random();
private Object lock1 = new Object();
private Object lock2 = new Object();
private static List<Integer> list1 = new ArrayList<Integer>();
private static List<Integer> list2 = new ArrayList<Integer>();
public void stageOne() {
synchronized (lock1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
list1.add(random.nextInt(100));
}
}
public void stageTwo() {
synchronized (lock2) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
list2.add(random.nextInt(100));
}
}
public void process() {
for(int i=0; i<1000; i++) {
stageOne();
stageTwo();
}
}
public static void show() {
System.out.println("List1: " + list1.size());
System.out.println("List2: " + list2.size());
}
}
public class JavaTest {
public static void main(String[] args) {
long start = System.currentTimeMillis();
Thread t1 = new Thread(new Worker());
t1.start();
Thread t2 = new Thread(new Worker());
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Completed.");
long end = System.currentTimeMillis();
System.out.println("Time taken: " + (end - start));
Worker.show();
}
}
When I run this program, I expect list1 and list2 to contain 2000 items each and for the program to take approximately 2000 milliseconds. However, lots of times I get lists less than 2000 items, although it does finish around 2000 milliseconds. Sometimes I even get a ArrayOutOfBounds Exception
Started.
Started.
Exception in thread "Thread-1" java.lang.ArrayIndexOutOfBoundsException: 163
at java.util.ArrayList.add(ArrayList.java:459)
at Worker.stageOne(JavaTest.java:34)
at Worker.process(JavaTest.java:53)
at Worker.run(JavaTest.java:14)
at java.lang.Thread.run(Thread.java:748)
Completed.
Time taken: 2217
List1: 1081
List2: 1079
I expect that each the locks in stageOne and stageTwo should stop the threads from interfering with each other. But that does not seem to be the case. What is the problem with this code?

Your lock objects are not static, so each thread is synchronizing on a different monitor. So the locks are not having any effect at all.

Related

how to create loops with threads (creates several new threads in a loop)?

how can I create a loop (or something else if that is a better way) where I can create some new threads.
So far I have 2 producer and consumer threads. But I would like to create, for example, 5 producers and 5 consumers, and each thread produced / consumed a different "product", two threads cannot do the same.
I'd like it to be something like this:
Produced thread0 produce 0
Consume thread0 consume 0
....
Produced thread4 produce 4
Consume thread4 consume 4
Thank you for every hint.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumer {
public static void main(String[] args) throws InterruptedException {
BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(2);
Thread producerThread = new Thread(new Runnable() {
#Override
public void run() {
try {
int value = 0;
while (true) {
blockingQueue.put(value);
System.out.println("Produced " + value);
value++;
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread consumerThread = new Thread(new Runnable() {
#Override
public void run() {
try {
while (true) {
int value = blockingQueue.take();
System.out.println("Consume " + value);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
producerThread.start();
consumerThread.start();
producerThread.join();
consumerThread.join();
}
}
Use a thread pool (Executors.newFixedThreadpool or Executors.newCachedThreadPool)
Don't forget to manage thread synchronization for resources using synchronized blocks.
Use volatile keyword for values that will be written/read simutaneously by several threads (see What is the volatile keyword useful for?)
I've used lambda syntax to redefine your runnables for clarity.
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class ProducerConsumer {
private static volatile int prodValue = 0;
private static final Object valueSync = new Object();
public static void main(String[] args) throws InterruptedException {
final BlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(2);
final ExecutorService threadPool = Executors.newCachedThreadPool();
final Runnable producer = () -> {
try {
while (true) {
synchronized(valueSync) {
blockingQueue.put(prodValue);
System.out.println(Thread.currentThread().getId() + " Produced " + prodValue);
prodValue++;
}
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
final Runnable consumer = () -> {
try {
while (true) {
int value = blockingQueue.take();
System.out.println(Thread.currentThread().getId() + " Consumed " + value);
Thread.sleep(1200);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
};
for (int i = 0; i < 5; i++) { //Create 5 threads of each
System.out.println("Loop " + i);
threadPool.execute(producer);
threadPool.execute(consumer);
Thread.sleep(500); //Wait a little
}
System.out.println("Loop done");
//Wait for all threads to complete with timeout
threadPool.awaitTermination(15, TimeUnit.SECONDS);
System.out.println("STOP !");
//Forceful shutdown of all threads (will happen as all threads are in a while(true) loop
threadPool.shutdownNow();
}
}
About synchronization: here you want your value to be added to the queue and incremented seemingly at once (atomically). synchronized around the operations prevents threads from simultaneously running this piece of code, which would result in the same value added multiple times into the queue, and then incremented multiple times (it happens if you decrease the Thread.sleep values to something close to 0 and remove the synchronized block).
I could have used blockingQueue as argument for synchronized but chose to use a dedicated object to make it more obvious.

why does deadlock not happen

Deadlock describes a situation where two more threads are blocked because of waiting for each other forever. When deadlock occurs, the program hangs forever and the only thing you can do is to kill the program.
why deadlock does not happen in example producer consumer problem given below:
I wonder why call wait method in synchronized block does not causing deadlock when synchronized object is waiting for release of lock from other thread ?
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class WaitAndNotify {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
var th1 = new Thread(new Producer(list));
var th2 = new Thread(new Consumer(list));
th1.start();
th2.start();
}
}
class Producer implements Runnable {
private List<Integer> list;
private final Integer MAX_SIZE_LIST = 5;
public Producer(List<Integer> list) {
this.list = list;
}
#Override
public void run() {
Random rand = new Random();
for (;;) {
synchronized (this.list) {
if (list.size() == MAX_SIZE_LIST) { // check list is full or not
try {
System.out.println("list full wait producer");
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
var randNumber = rand.nextInt();
System.out.println("produce number => " + randNumber);
list.add(randNumber);
list.notify();
}
}
}
}
class Consumer implements Runnable {
private List<Integer> list;
public Consumer(List<Integer> list) {
this.list = list;
}
#Override
public void run() {
for (;;) {
synchronized (this.list) {
if (list.size() == 0) {
try {
System.out.println("list empty consumer wait");
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("consume number <= " + list.remove(0));
list.notify();
}
}
}
}
You probably think, that Consumer will block at list.wait() and Producer will block at synchronized (this.list).
It works, because list.wait() releases the ownership of list inside a synchronized block. After wait returns, the thread acquires the ownership again.
See Object.wait()
As we have already discussed here Deadlock did not happen because of the use of synchronized block, list.wait() and list.notify() methods.
Here is a nice example of deadlock : https://docs.oracle.com/javase/tutorial/essential/concurrency/deadlock.html

Synchronization: multiple locks - create lock objects?

A quick (I think) concurrency question: I'm going through a multithreading course at Udemy.com, and the teacher talked through the code below. Although he explained it, I'm still not sure why you would create the lock1 and lock2 objects rather than locking on list1 and list2.
App.java:
public class App {
public static void main(String[] args) {
Worker worker = new Worker();
worker.main();
}
}
Worker.java:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Worker {
private Random random = new Random();
private Object lock1 = new Object();
private Object lock2 = new Object();
private List<Integer> list1 = new ArrayList<Integer>();
private List<Integer> list2 = new ArrayList<Integer>();
public void stageOne() {
synchronized (lock1) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list1.add(random.nextInt(100));
}
}
public void stageTwo() {
synchronized (lock2) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
list2.add(random.nextInt(100));
}
}
public void process() {
for(int i=0; i<1000; i++) {
stageOne();
stageTwo();
}
}
public void main() {
System.out.println("Starting ...");
long start = System.currentTimeMillis();
Thread t1 = new Thread(new Runnable() {
public void run() {
process();
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
process();
}
});
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
long end = System.currentTimeMillis();
System.out.println("Time taken: " + (end - start));
System.out.println("List1: " + list1.size() + "; List2: " + list2.size());
}
}
I don't think the motivation for that is expressed in the code you gave, but it is generally a best practice. However, the same best practice demands that the lock objects be final as well.
If the lists in question were either accepted from the outside or exposed to the outside via a method, then the benefit of the separate lock objects becomes more obvious: it is never a good idea to expose your locks to alien code because the alien code can then use them on its own for locking, breaking your own usage pattern.
If the lists are strictly private, then their monitors would be usable for internal locking; however, a later change to the access policy on the lists may inadvertently affect the locking policies. So, starting out with private locks also serves to avoid any future bugs.

Cyclic Barrier in java

I have a list which needs to be populated by three parties(threads,lets say).I am using cyclic barrier to achieve this functionality. Everything works fine except that I am not able to use the resulted list without inducing a forced sleep. Below is the code :
public class Test{
List<Integer> item = new Vector<Integer>();
public void returnTheList(){
CyclicBarrier cb = new CyclicBarrier(3, new Runnable() {
#Override
public void run() {
System.out.println("All parties are arrived at barrier, lets play -- : " + CyclicBarrierTest.getTheList().size());
//Here I am able to access my resulted list
}
});
CyclicBarrierTest sw1 = new CyclicBarrierTest(cb, new ZetaCode(1500), s);
CyclicBarrierTest sw2 = new CyclicBarrierTest(cb, new ZetaCode(1500),s);
CyclicBarrierTest sw3 = new CyclicBarrierTest(cb, new ZetaCode(1500),s);
Thread th1 = new Thread(sw1, "ZetaCode1");
Thread th2 = new Thread(sw2, "ZetaCode2");
Thread th3 = new Thread(sw3, "ZetaCode3");
th1.start();
th2.start();
th3.start();
}
public static void main(String args[]){
System.out.println("asdfasd");
Test test = new Test();
//ActionClass ac = new ActionClass();
test.returnTheList();
System.out.println("Inside the main method...size of the final list : " +test.item.size() );
}
Below is my CyclicBrrierTest class :
public class CyclicBarrierTest implements Runnable{
private CyclicBarrier barrier;
private Object obj;
static volatile String s = "";
volatile List<Integer> finalIntList = new Vector<Integer>();
public CyclicBarrierTest(CyclicBarrier barrier, Object obj, String s){
this.barrier = barrier;
this.obj = obj;
}
#Override
public void run(){
try{
System.out.println(Thread.currentThread().getName() + " is waiting on barrier and s is now : " + finalIntList.size());
ZetaCode simple = (ZetaCode)obj;
finalIntList.addAll(simple.getTheItemList());
barrier.await();
System.out.println(Thread.currentThread().getName() + " has crossed the barrier");
}catch(InterruptedException ex){
System.out.println("Error.." + ex.getMessage());
}catch(Exception e){
System.out.println("Error.." + e.getMessage());
}
}
public List<Integer> getTheList(){
return finalIntList;
}
So if I run this code without giving any delay the print statement in my main method gives me the length of my list as zero,however after giving an appropriate sleep it gives me the expected output.I want to achieve the same without giving any delay.Any help would be appreciated.
Thanks in advance.
It seems you'd want to use a CountDownLatch, not a CyclicBarrier here. The CyclicBarrier is working exactly as intended - your main method just isn't waiting for it to be tripped by all 3 threads. When you give it a sleep statement, the other 3 threads just happen to finish before main wakes up again.
A CyclicBarrier is useful when you need N workers to all reach the same 'checkpoint' before proceeding, and the workers themselves are the only ones who care. However, you have an N + 1 user here, the main thread, who wants to know when they're all done, and CyclicBarrier doesn't support that use case.
Note, of course that you can also use both of them.
In this code we have 4 tasks . Task1, Task2, Task3 producing int values and Task4 will add all the int values . Task4 is waiting after calling await() for Task1, Task2, Task3 to produce values.When they produce values they call await() method and Task 4 will add their values and print the o/p and call reset() method so the barrier will reset. After reset this process will continue again
package practice;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class CyclicbarrierExample {
public static void main(String[] args) {
CyclicBarrier c = new CyclicBarrier(4);
Task1 t1 = new Task1(c);
Task2 t2 = new Task2(c);
Task3 t3 = new Task3(c);
Task4 t4 = new Task4(c);
t1.start();
t2.start();
t3.start();
t4.start();
}
}
class Task1 extends Thread {
CyclicBarrier c;
static int t1 ;
public Task1(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (true) {
t1 = t1 + 1;
try {
c.await();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Task2 extends Thread {
CyclicBarrier c;
static int t2;
public Task2(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (true) {
t2 = t2 + 1;
try {
c.await();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
class Task3 extends Thread {
CyclicBarrier c;
static int t3;
public Task3(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (true) {
t3 = t3 + 1;
try {
c.await();
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
}
}
class Task4 extends Thread {
CyclicBarrier c;
static int t4;
static int count=0;
public Task4(CyclicBarrier c) {
this.c = c;
}
#Override
public void run() {
while (count<10) {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
t4 = Task1.t1 + Task2.t2 + Task3.t3;
System.out.println(t4);
try {
c.reset();
} catch (Exception e) {
System.out.println("yo");
}
count++;
}
}
}

Interview: How to ensure that a thread runs after another?

There are thread T1, T2 and T3, how can we ensure that thread T2 run after T1 and thread T3 run after T2?
This question was asked in my interview. I didn't answer. Please explain in detail.
This would be the simplest, dumbest approach:
final Thread t1 = new Thread(new T1()); // assume T1 is a Runnable
t1.start();
t1.join();
final Thread t2 = new Thread(new T2());
t2.start();
t2.join();
final Thread t3 = new Thread(new T3());
t3.start();
t3.join();
The obvious, and simplest, way has already been posted by #Assylias - have T1 run method create/start T2 and T2 run method create/start T3.
It is, IMHO, verging on pointless, but it could be done.
Solutions using Join() do not answer the question - they ensure that the termination of the threads is ordered, not the running of them. If the interviewr does not get that, you need to find another job anyway.
In an interview, my answer would be 'For * sake why? Threads are ususally used to avoid exactly what you are asking!'.
One way to do it would be something like the following. It's complex though. You might want to use the java.util.concurrent.CyclicBarrier class for this.
Each thread when it finishes sets the boolean value and notifies the next thread to continue. Even though it is an AtomicBoolean class, we need the synchronized so we can wait() and notify() on it.
It would be cleaner to pass in the lock objects or maybe have a begin() method on T2 and T3 so we can hide the locks inside of those objects.
final Object lock2 = new Object();
final Object lock3 = new Object();
boolean ready2;
boolean ready3;
...
public T1 implements Runnable {
public void run() {
...
synchronized (lock2) {
// notify the T2 class that it should start
ready2 = true;
lock2.notify();
}
}
}
...
public T2 implements Runnable {
public void run() {
// the while loop takes care of errant signals
synchronized (lock2) {
while (!ready2) {
lock2.wait();
}
}
...
// notify the T3 class that it should start
synchronized (lock3) {
ready3 = true;
lock3.notify();
}
}
}
...
public T3 implements Runnable {
public void run() {
// the while loop takes care of errant signals
synchronized (lock3) {
while (!ready3) {
lock3.wait();
}
}
...
}
}
There are thread T1, T2 and T3, how can we ensure that thread T2 run
after T1 and thread T3 run after T2?
OR
There are three threads T1, T2 and T3? How do you ensure sequence T1, T2, T3 in Java?
The question basically is T3 should finish first , T2 second and T1 last.
We can use use join() method of thread class.
To ensure three threads execute you need to start the last one first e.g. T3 and then call join methods in reverse order e.g. T3 calls T2.join,
and T2 calls T1.join. In this way, T1 will finish first and T3 will finish last.
public class Test1 {
public static void main(String[] args) {
final Thread t1 = new Thread(new Runnable() {
public void run() {
System.out.println("start 1");
System.out.println("end 1");
}//run
});
final Thread t2 = new Thread(new Runnable() {
public void run() {
System.out.println(" start 2 ");
try {
t1.join(2000);
} catch (Exception e) {
e.getStackTrace();
}
System.out.println(" end 2");
}
}) ;
final Thread t3 = new Thread( new Runnable() {
public void run() {
System.out.println(" start 3 ");
try {
t2.join(4000);
}catch(Exception e) {
e.getStackTrace();
}
System.out.println(" end 3 ");
}
});
// we are reversing the order of the start() method
t3.start();
t2.start();
t1.start();
}
}
From the output, You can see that threads have started in different order as you don't know which thread will get CPU. Its the decision of the Thread Scheduler, so we cannot do anything. But, you can see that threads are finished in correct order i.e. T1 then T2 and then T3.
There is another way of doing it. The pseudo code is :
t1.start();
t1.join(); // signals t2 to wait
if( !t1.isAlive()) {
t2.start();// if t1 is finished then t2 will start
}
t2.join();//signals t3 to wait
if (!t2.isAlive()) {
t3.start();
}
Let's take a full program:
public class Tic implements Runnable{
public void run() {
try {
for (int i = 0; i < 2; i++) {
System.out.println("tic");
}
} catch (Exception e) {
// TODO: handle exception
e.getStackTrace();
}
}
}
public class Tac implements Runnable{
public void run() {
try {
for (int i = 0; i < 2; i++) {
System.out.println("tac");
}
} catch (Exception e) {
// TODO: handle exception
e.getStackTrace();
}
}
}
public class Toe implements Runnable{
public void run() {
try {
for (int i = 0; i < 2; i++) {
System.out.println("toe");
}
} catch (Exception e) {
// TODO: handle exception
e.getStackTrace();
}
}
}
public class RunThreads1 {
public static void main(String[] args) {
try {
Tic tic = new Tic();
Tac tac = new Tac();
Toe toe = new Toe();
Thread t1 = new Thread(tic);
Thread t2 = new Thread(tac);
Thread t3 = new Thread(toe);
t1.start();
t1.join(); // signals t2 to wait
if( !t1.isAlive()) {
t2.start();// if t1 is finished then t2 will start
}
t2.join();//signals t3 to wait
if (!t2.isAlive()) {
t3.start();
}
}catch(InterruptedException e) {
e.printStackTrace();
}
}
}
The output is :
tic
tic
tac
tac
toe
toe
At the start of each thread (except t1), make it call join() on it's predecessor. Using executors (instead of threads directly) is another option. One could also look at using semaphores - T1 should release the permit upon completion, T2 should try to acquire two permits, and release them when done, T3 should try to acquire three permits & so on. Using join or executors would be the preferred route.
Threads are also runnables. You can simply run them sequentially:
t1.run();
t2.run();
t3.run();
This has obviously little interest.
Assuming they want the threads to run in parallel, one solution would be to have each thread start the next one, since the JMM guarantees that:
A call to start() on a thread happens-before any actions in the started thread.
Guess what interviewer asking was three threads do the work in sequence.For example if one thread prints 1,4,5...second 2,5,8 and thirds 3,6,9 etc..ur output should be 1,2,3,4,5.....
Ist thread prints 1 and gives chance to 2nd thread to print 2..etc.,
I tried it using cyclebarriers.As soon as 'one' prints 1it gives chance to two as it calls cb.wait,when two runs it will in turn call three in similar fashion and it will continue.Let me know if thr are any bugs in the code
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
class one implements Runnable{
CyclicBarrier cb;
one(CyclicBarrier cb){this.cb=cb;}
public void run(){
int i=1;
while(true)
{
System.out.println(i);
try {
Thread.sleep(1000);
cb.await();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
i=i+3;
}
}
}
class two implements Runnable{
CyclicBarrier cb;
int i=2;
two(CyclicBarrier cb){this.cb=cb;}
public void run(){
System.out.println(i);
try {
cb.await();
i=i+3;
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class oneTwoThree {
public static void main(String args[]){
Runnable threePrinter = new Runnable() {
int i=3;
public void run() {
System.out.println(i);
i=i+3;
}
};
CyclicBarrier bar2 =new CyclicBarrier(1,threePrinter);//, barrier1Action);
two twoPrinter =new two(bar2);
CyclicBarrier bar1 =new CyclicBarrier(1,twoPrinter);
Thread onePrinter=new Thread(new one(bar1));
onePrinter.start();
}
}
I tried in a much simpler way.. using a waits and notifies.(as opposed to cyclic barrier approach in my prev post).
It uses a 'State' class... which gets three states:1,2,3.(default 3).
When it is at 3, it triggers t1, at 1 will trigger t2, at 2 will trigger t3 and so on.
Classes:
State// int i=3
T1// prints 1,4,7...
T2// Prints 2,5,8
T3//Prints 3,6,9 etc.,
Please let me know your views or if any issues in the code. Thanks.
Here is the code.:
public class State {
private int state ;
public State() {
this.state =3;
}
public synchronized int getState() {
return state;
}
public synchronized void setState(int state) {
this.state = state;
}
}
public class T1 implements Runnable {
State s;
public T1(State s) {
this.s =s;
}
#Override
public void run() {
int i =1;
while(i<50)
{
//System.out.println("s in t1 "+ s.getState());
while(s.getState() != 3)
{
synchronized(s)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==3)
System.out.println("t1 "+i);
s.setState(1);
i = i +3 ;
s.notifyAll();
}
}
}
}
public class T2 implements Runnable {
State s;
public T2(State s) {
this.s =s;
}
#Override
public synchronized void run() {
int i =2;
while(i<50)
{
while(s.getState() != 1)
{
synchronized(s)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
//if(s.getState() ==3)
if(s.getState()==1)
System.out.println("t2 "+i);
s.setState(2);
i = i +3 ;
s.notifyAll();
}
}
}
}
public class T3 implements Runnable {
State s;
public T3(State s) {
this.s =s;
}
#Override
public synchronized void run() {
int i =3;
while(i<50)
{
while(s.getState() != 2)
{
synchronized(s)
{
try {
s.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
synchronized(s)
{
if(s.getState()==2)
System.out.println("t3 "+i);
i = i +3 ;
s.setState(3);
s.notifyAll();
}
}
}}
public class T1t2t3 {
public static void main(String[] args) {
State s = new State();
Thread t1 = new Thread(new T1(s));
Thread t2 = new Thread(new T2(s));
Thread t3 = new Thread(new T3(s));
t1.start();
t2.start();
t3.start();
}
}
how can we ensure that thread T2 run after T1 and thread T3 run after T2?
NOTE: Assuming that it is not about scheduling the threads in the required order
We could use the Condition Interface.
We'll need two conditions bound to a single Lock: condition1 to coordinate T1 and T2, condition2 to coordinate T2 and T3.Pass condition1 to T1 and T2, condition2 to T2 and T3.
So, we would have T2 await on condition1 in it's run method, which will be signalled by T1 (from T1's run method, after T1 starts/finishes its task). Similarly have T3 await on condition2 in it's run method, which will be signalled by T2 (from T2's run method, after it starts/finishes it's task).
Create a priority queue with each tread in the other they are created.
You can then apply Thread.join after it completes, remove that thread from the priority queue, and then execute the first element of the queue again.
Pseudocode:
pthread [3] my_threads
my_queue
for t in pthreads:
my_queue.queue(t)
while !my_queue.empty()
pop the head of the queue
wait until it complets
thread.join()
implementation is left as exercise, so next time you get it right!
Use the thread isAlive method before starting the thread T2 and T3.
Thread t1 = new Thread(new T1());
Thread t2 = new Thread(new T2());
Thread t3 = new Thread(new T3());
t1.start();
if(t1.isAlive()){
t2.start();
}
if(t2.isAlive()){
t3.start();
}
Try the below code while using that you can run n number of thread in that manner.
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class CyclicExecutionOfThreads {
public static void main(String args[]) {
int totalNumOfThreads = 10;
PrintJob printJob = new PrintJob(totalNumOfThreads);
/*
MyRunnable runnable = new MyRunnable(printJob, 1);
Thread t1 = new Thread(runnable);
MyRunnable runnable2 = new MyRunnable(printJob, 2);
Thread t2 = new Thread(runnable2);
MyRunnable runnable3 = new MyRunnable(printJob, 3);
Thread t3 = new Thread(runnable3);
t1.start();
t2.start();
t3.start();
*/
//OR
ExecutorService executorService = Executors
.newFixedThreadPool(totalNumOfThreads);
Set<Runnable> runnables = new HashSet<Runnable>();
for (int i = 1; i <= totalNumOfThreads; i++) {
MyRunnable command = new MyRunnable(printJob, i);
runnables.add(command);
executorService.execute(command);
}
executorService.shutdown();
}
}
class MyRunnable implements Runnable {
PrintJob printJob;
int threadNum;
public MyRunnable(PrintJob job, int threadNum) {
this.printJob = job;
this.threadNum = threadNum;
}
#Override
public void run() {
while (true) {
synchronized (printJob) {
if (threadNum == printJob.counter) {
printJob.printStuff();
if (printJob.counter != printJob.totalNumOfThreads) {
printJob.counter++;
} else {
System.out.println();
// reset the counter
printJob.resetCounter();
}
printJob.notifyAll();
} else {
try {
printJob.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class PrintJob {
int counter = 1;
int totalNumOfThreads;
PrintJob(int totalNumOfThreads) {
this.totalNumOfThreads = totalNumOfThreads;
}
public void printStuff() {
System.out.println("Thread " + Thread.currentThread().getName()
+ " is printing");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void resetCounter() {
this.counter = 1;
}
}
The concurrent package has better classes to use the shared object.
One of the way is like this.
public static void main(String[] args) {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
ThreadId threadId = new RunInSequence.ThreadId();
threadId.setId(1);
Thread t1 = setThread("thread1",lock, condition, 1, 2, threadId);
Thread t2 = setThread("thread2",lock, condition, 2, 3, threadId);
Thread t3 = setThread("thread3",lock, condition, 3, 1, threadId);
t1.start();
t2.start();
t3.start();
}
private static class ThreadId {
private int id;
public ThreadId() {
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
private static Thread setThread(final String name,final Lock lock, final Condition condition, int actualThreadId, int nextThreadId,
ThreadId threadId) {
Thread thread = new Thread() {
#Override
public void run() {
while (true) {
lock.lock();
try {
while (threadId.getId() != actualThreadId) {
try {
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+"prints: " + actualThreadId);
threadId.setId(nextThreadId);
condition.signalAll();
} finally {
lock.unlock();
}
}
}
};
return thread;
}
package thread;
class SyncPrinter {
public static void main(String[] args) {
SyncPrinterAction printAction1 = new SyncPrinterAction(new int[]{1,5,9,13}, true);
SyncPrinterAction printAction2 = new SyncPrinterAction(new int[]{2,6,10,14}, true);
SyncPrinterAction printAction3 = new SyncPrinterAction(new int[]{3,7,11,15}, true);
SyncPrinterAction printAction4 = new SyncPrinterAction(new int[]{4,8,12,16}, false);
printAction1.setDependentAction(printAction4);
printAction2.setDependentAction(printAction1);
printAction3.setDependentAction(printAction2);
printAction4.setDependentAction(printAction3);
new Thread(printAction1, "T1").start();;
new Thread(printAction2, "T2").start();
new Thread(printAction3, "T3").start();
new Thread(printAction4, "T4").start();
}
}
class SyncPrinterAction implements Runnable {
private volatile boolean dependent;
private SyncPrinterAction dependentAction;
int[] data;
public void setDependentAction(SyncPrinterAction dependentAction){
this.dependentAction = dependentAction;
}
public SyncPrinterAction( int[] data, boolean dependent) {
this.data = data;
this.dependent = dependent;
}
public SyncPrinterAction( int[] data, SyncPrinterAction dependentAction, boolean dependent) {
this.dependentAction = dependentAction;
this.data = data;
this.dependent = dependent;
}
#Override
public void run() {
synchronized (this) {
for (int value : data) {
try {
while(dependentAction.isDependent())
//System.out.println("\t\t"+Thread.currentThread().getName() + " :: Waithing for dependent action to complete");
wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
dependentAction.setDependent(true);
System.out.println(Thread.currentThread().getName() + " :: " +value);
dependent = false;
}
}
}
private void setDependent(boolean dependent) {
this.dependent = dependent;
}
private boolean isDependent() {
return dependent;
}
}
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
class Worker implements Runnable {
BlockingQueue<Integer> q = new LinkedBlockingQueue<>();
Worker next = null; // next worker in the chain
public void setNext(Worker t) {
this.next = t;
}
public void accept(int i) {
q.add(i);
}
#Override
public void run() {
while (true) {
int i;
try {
i = q.take(); // this blocks the queue to fill-up
System.out.println(Thread.currentThread().getName() + i);
if (next != null) {
next.accept(i + 1); // Pass the next number to the next worker
}
Thread.sleep(500); // Just sleep to notice the printing.
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class PrintNumbersSequentially {
public static void main(String[] as) {
Worker w1 = new Worker();
Worker w2 = new Worker();
Worker w3 = new Worker();
w1.setNext(w2);
w2.setNext(w3);
w3.setNext(w1);
new Thread(w1, "Thread-1: ").start();
new Thread(w2, "Thread-2: ").start();
new Thread(w3, "Thread-3: ").start();
//Till here all the threads have started, but no action takes place as the queue is not filled for any worker. So Just filling up one worker.
w1.accept(100);
}
}
I think this could help you out.
By using join you can ensure running of a thread one after another.
class MyTestThread implements Runnable{
public void run() {
System.out.println("==MyTestThread : START : "+Thread.currentThread().getName());
for(int i = 0; i < 10; i++){
System.out.println(Thread.currentThread().getName() + " :i = "+i);
}
System.out.println("==MyTestThread : END : "+Thread.currentThread().getName());
}
}
public class ThreadJoinTest {
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(new MyTestThread(), "t1");
Thread thread2 = new Thread(new MyTestThread(), "t2");
thread1.start();
thread1.join();
thread2.start();
thread2.join();
System.out.println("====All threads execution===completed");
}
}
package io.hariom.threading;
//You have three threads T1, T2, and T3, How do you ensure that they finish in order T1, T2, T3 ?
public class ThreadTest1 {
public static void main(String[] args) {
Thread thread1 = new Thread(new MyRunnable(null));
Thread thread2 = new Thread(new MyRunnable(thread1));
Thread thread3 = new Thread(new MyRunnable(thread2));
thread1.start();
thread2.start();
thread3.start();
}
}
class MyRunnable implements Runnable {
Thread t;
MyRunnable(Thread t) {
this.t = t;
}
#Override
public void run() {
if (t != null) {
try {
t.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " starts");
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " ends");
}
}
Here is my approach to the problem using CountDownLatch for signalling .
T1 thread after doing its job signal to T2 and T2 to T3.
public class T1T2T3 {
public static void main(String[] args) {
CountDownLatch c1 = new CountDownLatch(1);
CountDownLatch c2 = new CountDownLatch(1);
Thread T1 = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("T1");
c1.countDown();
}
});
Thread T2 = new Thread(new Runnable() {
#Override
public void run() {
//should listen to something from T1
try {
c1.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T2");
c2.countDown();
}
});
Thread T3 = new Thread(new Runnable() {
#Override
public void run() {
try {
c2.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("T3");
}
});
T1.start();
T3.start();
T2.start();
}
}

Categories

Resources