I want to display this two threads alternatively like that :
Thread 1
Thread 0
Thread 1
Thread 0
...
That's the basic code from where I started, I tried with wait() notify() Methods but I couldn't get the result wanted.
class Task extends Thread {
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {
}
}
}
public class App {
public static void main(String[] args) {
Task t1 = new Task() ;
Task t2 = new Task() ;
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
}
}
} ```
I see two solutions:
Busy Wait
Each thread wait before printing. And release when the condition is true. I used AtomicInteger for indexToPrint to make this value sync for every thread.
This solution works with n number of threads.
import java.util.concurrent.atomic.AtomicInteger;
class Task extends Thread {
final static private AtomicInteger indexToPrint = new AtomicInteger(0);
static private int threadNumber = 0;
final private int index;
/**
*
*/
public Task() {
index = threadNumber++;
}
private int nextIndex() {
return (index + 1) % threadNumber;
}
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
while (indexToPrint.get() != index) {
sleep((long) 10);
}
indexToPrint.set(nextIndex());
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {}
}
}
wait and notify
A bit more complex to understand, but no useless CPU use. Let's explain how the synchronized block synchronized (indexToPrint) {...} works.
The block is synchronized monitoring the static object indexToPrint. This object is static (common to every thread), so only one thread can simultaneously enter this block.
When one thread enter the block, if its index is different from indexToPrint then the thread is stopped with wait() making it possible for another thread to enter the block. Else, the thread name is printed, the indexToPrint is updated to next thread index and all thread are waken up with notifyAll(). Finally, it left the block.
All threads waiting are now awake, and the actual thread left the block. So one thread can try again to print.
It's important to understand that when a thread is put to wait and then notify, it runs exactly where it was stopped. Here, a thread can be stopped at two positions: before the synchronized block and at the wait call.
The while is very essential here. All thread are waking up with notifyAll(), so after waking up they should test themselves again.
You can find a good documentation here.
The code is based on the previous one. With same use of indexToPrint.
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
class Task extends Thread {
static private final AtomicInteger indexToPrint = new AtomicInteger(0);
static private int threadNumber = 0;
final private int index;
final private static ArrayList<Task> tasks = new ArrayList<>();
/**
*
*/
public Task() {
index = threadNumber++;
tasks.add(this);
}
private int nextIndex() {
return (index + 1) % threadNumber;
}
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
double dure = Math.random()*200 ;
sleep((long) dure);
synchronized (indexToPrint) {
while (indexToPrint.get() != index) {
indexToPrint.wait();
}
indexToPrint.set(nextIndex());
System.out.println(Thread.currentThread().getName());
indexToPrint.notifyAll();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
The random sleep time can cause the unexpected result also within the main method making the main thread sleep between the start of Thread1 and Thread2 can help you to know who is the first thread that will start the print task , after that you should give the right sleep time inside the task to give the Threads the possibility to prints alternatively .
class Task extends Thread {
#Override
public void run() {
try {
for(int i = 0; i<10; i++){
sleep(2000);
System.out.println(Thread.currentThread().getName());
}
} catch (Exception e) {
}
}
}
public class App {
public static void main(String[] args) {
Task t1 = new Task() ;
Task t2 = new Task() ;
t1.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
t2.start();
}
}
Related
I'm new to threads. I wanted to get two threads to increment an integer to a certain value. because int type is immutable, I switched to atomic integer. I also tried to wrap an int to a class and that didn't work either. I also tried static/volatile int and that didn't work. I also tried to use fairness policy. The main issue is that "counterObj" is not incremented correctly and is still set to 0 even though it is injected to both threads.
My expected running behavior:
thread value
thread 0 0
thread 1 1
thread 0 2
...
What I wrote so far:
import java.util.concurrent.atomic.AtomicInteger;
public class Application {
public static void main(String[] args) {
Application app = new Application();
try {
app.launch();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void launch() throws InterruptedException {
int increments = 100;
AtomicInteger counterObj = new AtomicInteger(0);
CounterThread th1 = new CounterThread("1", counterObj, increments);
CounterThread th2 = new CounterThread("2", counterObj, increments);
th1.start();
th2.start();
System.out.println(counterObj.get());
}
}
and
import java.util.concurrent.atomic.AtomicInteger;
public class CounterThread implements Runnable {
private final String threadID;
private AtomicInteger counterObj;
private int bound;
public CounterThread(String threadID, AtomicInteger counter, int bound) {
this.threadID = threadID;
this.counterObj = counter;
this.bound = bound;
}
#Override
public synchronized void run() {
while (counterObj.get() < bound) {
synchronized (this) {
counterObj.incrementAndGet();
}
}
System.out.println("Thread " + threadID + " finished");
}
public void start() throws InterruptedException {
Thread thread = new Thread(this, threadID);
thread.join();
thread.start();
}
}
Cheers!
I think your program is exiting before your threads get a chance to do anything (probably due to the ordering of your starts and joins. I would move your thread starting logic into your main(or launch) method. Something like the following.
Thread thread1 = new Thread(new MyCounterRunnable("1", counterObj, increments));
Thread thread2 = new Thread(new MyCounterRunnable("2", counterObj, increments));
Then, in your main, you need to call join after starting the threads...as follows:
thread1.start(); // starts first thread.
thread2.start(); // starts second thread.
thread1.join(); // don't let main exit until thread 1 is done.
thread2.join(); // don't let main exit until thread 2 is done.
What you really are wanting is for only one thread to increment an int at a time.
The int variable is the resource you want in the synchronized block, so the different threads can increment it one at a time.
This can be done using syncrhonize alone.
Disclaimer: I didn't run the code so it could have some typo or Exceptions to be removed from the Application class.
public class Application {
private int theVar = 0;
private int increments = 100;
public static void main(String[] args) {
Application app = new Application();
try {
app.launch();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized addOne(){
this.theVar++;
}
private void launch() throws InterruptedException {
Runnable counter1 = new Counter(this, increments), counter2 = new Counter(this, increments);
Thread t1 = new Thread(counter1);
Thread t2 = new Thread(counter2);
t1.start();
t2.start();
}
}
A counter class
public class Counter implements Runnable{
private Application app;
int rounds = -1;
public Counter(Application app, rounds){
this.app = app;
this.rounds = rounds;
}
public void run(){
while(int i=0; i<rounds; i++){
this.app.addOne();
}
}
}
AtomicInteger takes care of atomicity itself, so you shouldn't need to use synchronized -- but only if you play by the rules, and do your atomic operations in one call.
You're failing to do this, because you call counterObj.get() then depending on the result counterObj.incrementAndGet(). You need to avoid this because you want the check and the update to be part of the same atomic chunk of work.
You can get close with:
while(counterObj.incrementAndGet() < bound) {} ;
But this will always increment at least once, which may be once too many.
Slightly more involved:
IntUnaryOperator incrementWithLimit = x ->
( x < bound ? x + 1 : x );
while(counterObj.updateAndGet(incrementWithLimit) < bound) {};
That is, we've created a function that increments a number only if it's lower than bound, and we tell AtomicInteger to apply that.
There are a couple of issues with your code:
Thread.join method works only if the thread has started, else it does nothing. So you must reorder your code, but if you just move the join method after start, when starting the first thread by calling CounterThread.start, the main thread will wait until the started thread has finished, blocked in the Thread.join method, and only then will continue to starting the second one. A solution is to make an additional method in the CounterThread class, that will be called after both threads have been started:
public void waitFinish() throws InterruptedException {
thread.join();
}
synchronized (this) is synchronizing on the CounterThread instance that has been created when you called new CounterThread(...), but you have two instances so each will be synchronizing on a different object. For synchronized to work, you need to use a common instance of an object, in this case you can use the shared counterObj.
Only the AtomicInteger methods are guaranteed to be thread safe, so after you check if the bound has been reached outside the synchronized block, when entering the synchronized block the value can already be changed by another thread. So you need to do a recheck inside the synchronized block OR to first synchronize on the shared lock(counterObj) before the check and increment.
while (true) {
synchronized (counterObj) {
if (counterObj.get() < bound)
counterObj.incrementAndGet();
else break;
}
}
Note that the AtomicInteger class synchronized methods aren't helping now, but because it is a mutable object, it helps to use it as a shared lock. If you used an Integer instead, being immutable, a new instance will have been created when you incremented it. So now, it's only function is a wrapper holding the integer result.
Putting it all together:
public class Application {
public static void main(String[] args) {
Application app = new Application();
try {
app.launch();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void launch() throws InterruptedException {
int increments = 100;
AtomicInteger counterObj = new AtomicInteger(0);
CounterThread th1 = new CounterThread("1", counterObj, increments);
CounterThread th2 = new CounterThread("2", counterObj, increments);
th1.start();
th2.start();
th1.waitFinish();
th2.waitFinish();
System.out.println(counterObj.get());
}
}
public class CounterThread implements Runnable {
private final String threadID;
private AtomicInteger counterObj;
private int bound;
private Thread thread;
public CounterThread(String threadID, AtomicInteger counter, int bound) {
this.threadID = threadID;
this.counterObj = counter;
this.bound = bound;
}
#Override
public void run() {
while (true) {
synchronized (counterObj) {
if (counterObj.get() < bound)
counterObj.incrementAndGet();
else break;
}
}
System.out.println("Thread " + threadID + " finished");
}
public void start() throws InterruptedException {
thread = new Thread(this, threadID);
thread.start();
}
public void waitFinish() throws InterruptedException {
thread.join();
}
}
I've included a double check on the AtomicInteger, this appears to be what you've been trying to accomplish.
import java.util.concurrent.atomic.AtomicInteger;
public class DualCounters{
public static void main(String[] args) throws Exception{
AtomicInteger i = new AtomicInteger(0);
int bounds = 3;
Thread a = new Thread(()->{
int last = 0;
while(i.get()<bounds){
synchronized(i){
if(i.get()<bounds){
last = i.getAndIncrement();
}
}
}
System.out.println("a last " + last);
});
Thread b = new Thread(()->{
int last = 0;
while(i.get()<bounds){
synchronized(i){
if(i.get()<bounds){
last = i.getAndIncrement();
}
}
}
System.out.println("b last " + last);
});
a.start();
b.start();
a.join();
b.join();
System.out.println(i.get() + " afterwards");
}
}
The double check is a broken concept in java, the AtomicInteger offers tools for accomplishing this without any synchronization.
int a;
while((a = i.getAndIncrement())<bounds){
...
}
Now a will never be greater than bounds inside of the while loop. When the loop is finished i and a could have a value greater than bounds.
If that was an issue, there is always the other method getAndUpdate
while((a = i.getAndUpdate(i->i<bounds?i+1:i)<bounds){
...
}
I am trying to work around with threads in java. Though I understand that threads output are unpredictable, However was wondering if there is a way to do that.
I have to implement two threads, one prints alphabets(a,b,c...z) and other prints numbers(1,2,3....26). Have to implement it in such a way that the output should be a,1,b,2,c,3,d,4......z,26. Below is my code but it doesn't give the desired output.
public class ThreadsExample {
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
System.out.print(i+",");
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
System.out.print(i+",");
}
}
}
What tweak should I make in the code to get the desired output? How does synchronization helps here? Or is it really possible when working with Threads at all?
PS: This is not an assignment or some exercise. Its self learning.
It is possible. You need to synchronize it well.
Approach Pseudocode
query some (synchronized) state
state will tell whether nums or chars are allowed
if state allows char and caller will put chars, do it now and change state and wake up waiting threads
if not, wait
if state allows numbers and caller will put numbers, do it now and change state and wake up waiting threads
if not, wait
Java code
public class ThreadsExample {
public static ThreadsExample output = new ThreadsExample ();
public static void main(String[] args) {
Runnable r = new Runnable1();
Thread t = new Thread(r);
Runnable r2 = new Runnable2();
Thread t2 = new Thread(r2);
t.start();
t2.start();
}
private Object syncher = new Object (); // we use an explicit synch Object, you could use annotation on methods, too. like ABHISHEK did.
// explicit allows to deal with more complex situations, especially you could have more the one locking Object
private int state = 0; // 0 allows chars, 1 allows ints
public void print (char pChar) {
synchronized (syncher) { // prevent the other print to access state
while (true) {
if (state == 0) { // char are allowed
System.out.print(pChar + ","); // print it
state = 1; // now allow ints
syncher.notify(); // wake up all waiting threads
return;
} else { // not allowed for now
try {
syncher.wait(); // wait on wake up
} catch (InterruptedException e) {
}
}
}
}
}
public void print (int pInt) {
synchronized (syncher) {
while (true) {
if (state == 1) {
System.out.print(pInt + ",");
state = 0;
syncher.notify();
return;
} else {
try {
syncher.wait();
} catch (InterruptedException e) {
}
}
}
}
}
}
class Runnable2 implements Runnable{
public void run(){
for(char i='a';i<='z';i++) {
ThreadsExample.output.print(i);
}
}
}
class Runnable1 implements Runnable{
public void run(){
for(int i=1;i<=26;i++) {
ThreadsExample.output.print(i);
}
}
}
Output
a,1,b,2,c,3,d,4,e,5,f,6,g,7,h,8,i,9,j,10,k,11,l,12,m,13,n,14,o,15,p,16,q,17,r,18,s,19,t,20,u,21,v,22,w,23,x,24,y,25,z,26,
The whole idea of threads: it represents a "stream of activity" that executes code independent of other threads.
In your case, you want that these two threads go in "lockstep". Thread A does one step, then Thread B, then A, then B.
In order to get there, the two threads need something "synchronize" on - in other words: A sends a signal to B when it has done its steps - and B has to wait for that signal. Then B does its thing, signals to A, ...
For starters, a simple boolean value would do. One thread sets it to true, the other to false (to indicate when it has made its step). Then the thread waits for the boolean to toggle again.
As you intend to learn things, I would just start experimenting from there. In case you want to take detours, look here for example. This might help as well.
HERE IS THE CODE::
You need to create 2 threads and implement wait and notify methods correctly you can also refer "Create two threads, one display odd & other even numbers" for your answer.
public class ThreadClass {
volatile int i = 1;
volatile Character c = 'a';
volatile boolean state = true;
synchronized public void printAlphabet() {
try {
while (!state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " +c);
state = false;
c++;
notifyAll();
}
synchronized public void printNumbers() {
try {
while (state) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " " + i);
state = true;
i++;
notifyAll();
}
public static void main(String[] args) {
ThreadClass threadClass = new ThreadClass();
Thread t1 = new Thread() {
int k = 0;
#Override
public void run() {
while (k < 26) {
threadClass.printAlphabet();
k++;
}
}
};
t1.setName("Thread1");
Thread t2 = new Thread() {
int j = 0;
#Override
public void run() {
while (j < 26) {
threadClass.printNumbers();
j++;
}
}
};
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Your threads are running at the same time. But not the way you want it, as mentioned above. You will see blocks of data from thread 1 and then a block of data from thread 2; and this is because of thread scheduling. Thread 1 is just queuing its output before thread 2.
To test this theory, increase your output to a 1000 records for example as the alphabet and 26 numbers are not as large to see this.
By doing so, you will see these 'blocks' of data. There is a way to do what you mentioned, but it is not advisable as this is not demonstrating how threads actually work but rather you forcing it to work that way.
With less Code:
class MyRunnable implements Runnable {
private static int n = 1;
private static char c = 'a';
public void run() {
for (int i = 1; i <= 26; i++) {
synchronized (this) {
try {
notifyAll();
if (Thread.currentThread().getName().equals("A")) {
System.out.print(c + ",");
c++;
} else {
System.out.print(n + ",");
n++;
}
if (i != 26) {
wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class PrintAlphabetNumberJob {
public static void main(String[] args) throws InterruptedException {
MyRunnable r = new MyRunnable();
Thread tAlphabet = new Thread(r, "A");
Thread tNumber = new Thread(r, "N");
tAlphabet.start();
Thread.sleep(100);
tNumber.start();
}
}
So, i apologize for the title. It's quite hard to explain in one sentence what i would like to do if you have no idea on how it is called.
So assume i can only use primitive thread functions (wait, notify, no concurrent package)
The program has 3 threads, all of them are the same and are called by the main thread. They behave normally until one of the three get an exception and so it must wait for the end of the remaining 2 threads in order to start a recovery process.
I was thinking about a static variable but I'm not really sure about it, i would love to keep it as simple as possible.
Each thread starts at the same time.
I don't see any reason why you can't use a static variable like you suggest. Here's how I would do it with an inner class...
private static boolean running = true;
public void test26546397() {
while (true) {
Thread t1 = new Thread(new MyRunnable());
Thread t2 = new Thread(new MyRunnable());
Thread t3 = new Thread(new MyRunnable());
t1.start();
t2.start();
t3.start();
try {
t1.join();
t2.join();
t3.join();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
running = true;
// Do recovery
}
}
public class MyRunnable implements Runnable {
#Override
public void run() {
while (running) {
try {
// doStuff
} catch (Exception ex) {
running = false;
}
}
}
}
I would of course replace the while (true) with something a little more suitable.
I think you need java.concurrent.CountdownLatch, however if the java.concurrent package is not available to you can code this yourself using Object.wait/notify and synchronized blocks.
The latch can then be decremented in a finally {} on each Thread, this will be run if the Thread completes, or an exception occurs.
Your main program then just needs to wait for count to become 0.
public class StackOverflow26546397 {
static class CountdownLatch {
private int count;
private Object monitor = new Object();
public CountdownLatch(int count) {
this.count = count;
}
public void countDown() {
synchronized (monitor) {
count--;
monitor.notifyAll();
}
}
public void await() throws InterruptedException {
synchronized (monitor) {
while (count > 0) {
monitor.wait();
}
}
}
}
static class Job implements Runnable {
private CountdownLatch latch;
public Job(CountdownLatch latch) {
this.latch = latch;
}
#Override
public void run() {
try {
// do work.
Thread.sleep((long) (Math.random() * 3000d));
} catch (InterruptedException e) {
//
} finally {
latch.countDown();
}
}
}
public static void main(String[] args) throws InterruptedException {
CountdownLatch latch = new CountdownLatch(3);
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
new Thread(new Job(latch)).start();
latch.await();
System.out.println("All threads finished");
}
}
Not sure what you are trying to do but this is as simple as I can think of (just native concurrency):
Create a static or shared volatile boolean
private static volatile boolean exceptionOccured=false
Set the above to 'true' when exception occurs:
....}catch(Exception e){
exceptionOccured=true;
}
Check this periodically in you normal thread flow:
if (exceptionOccured)
//enter you synchronized call here
the synchronized method could look something like:
public synchronized void checkAndRecover(){
//decrement a counter or other logic to identify which is the last Thread and then
//perform any recovery logic
}
I research concurrecy in java. Recently I learn wait and notify methods meaning.
Now I think that sometimes I should to solve following problem:
I have
class ThreadGroup1 extends Thread
and
class ThreadGroup2 extends Thread
I have 300 instances of every Thread and start simultaneously (for example by means of CountDownLatch )
And I have synchronized section:
synchronized(SharedObjectBetweenThreads){...}
I want to get following behaviour:
instance of ThreadGroup1 acquire the section
instance of ThreadGroup2 acquire the section
instance of ThreadGroup1 acquire the section
instance of ThreadGroup2 acquire the section
and so on.
I think you understand what I want.
I know that if I would use wait and notify I cannot guarantee which next thread from waiting queue will acquire section.
How can I solve described issue?
P.S.
This issue relates with question "how to notify concrete thread?"
P.S.
my current sketch
public class ConditionTest {
public static void main(String [] args){
List<Thread> threads = new ArrayList<>();
for(int i=0 ;i<10;i++) {
threads.add(new Thread1());
threads.add(new Thread2());
}
for(Thread thread : threads){
thread.start();
}
}
public static synchronized void method() throws InterruptedException {
System.out.println(Thread.currentThread());
Thread.sleep(500);
}
}
class Thread1 extends Thread{
static int index =0;
int number;
#Override
public void run(){
try {
ConditionTest.method();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
#Override
public String toString(){
return "group1-" + number;
}
Thread1(){
number= index++;
}
}
class Thread2 extends Thread{
static int index =0;
int number;
#Override
public void run(){
try {
ConditionTest.method();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
#Override
public String toString(){
return "group2-" + number;
}
Thread2(){
number= index++;
}
}
please help to correct this.
According hoaz answer I got resolving.
please review this code:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class ConditionTest {
static Integer CountThreadInGroup = 10;
public static void main(String[] args) throws InterruptedException {
Lock lock = new ReentrantLock();
boolean isFirstShouldExecute = true;
Condition isFirstExpected = lock.newCondition();
Condition isSecondExpected = lock.newCondition() ;
Synchronizator synchronizator = new Synchronizator(isFirstShouldExecute, lock,isFirstExpected,isSecondExpected);
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < CountThreadInGroup; i++) {
threads.add(new Thread1(synchronizator));
}
for (Thread thread : threads) {
thread.start();
}
threads.clear();
Thread.sleep(100);
for (int i = 0; i < CountThreadInGroup; i++) {
threads.add(new Thread2(synchronizator));
}
for (Thread thread : threads) {
thread.start();
}
}
public static void method() throws InterruptedException {
System.out.println(Thread.currentThread());
Thread.sleep(500);
}
}
class Thread1 extends Thread {
static int index = 0;
int number;
private final Synchronizator synchronizator;
#Override
public void run() {
synchronizator.lock.lock();
try {
while (!synchronizator.isFirstExpected) {
synchronizator.isFirstShouldExecute.await();
System.out.println(Thread.currentThread() + " woke up");
}
ConditionTest.method();
synchronizator.isFirstExpected = false;
synchronizator.isSecondShouldExecute.signal();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
synchronizator.lock.unlock();
}
}
#Override
public String toString() {
return "\t\t\t group1-" + number;
}
Thread1(Synchronizator synchronizator) {
this.synchronizator = synchronizator;
number = index++;
}
}
class Thread2 extends Thread {
static int index = 0;
int number;
private final Synchronizator synchronizator;
#Override
public void run() {
synchronizator.lock.lock();
try {
while (synchronizator.isFirstExpected) {
synchronizator.isSecondShouldExecute.await();
System.out.println(Thread.currentThread() + " woke up");
}
ConditionTest.method();
synchronizator.isFirstExpected = true;
synchronizator.isFirstShouldExecute.signal();
} catch (InterruptedException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
} finally {
synchronizator.lock.unlock();
}
}
#Override
public String toString() {
return "\t\t\t\t\t\t group2-" + number;
}
Thread2(Synchronizator synchronizator) {
this.synchronizator = synchronizator;
number = index++;
}
}
class Synchronizator{
volatile boolean isFirstExpected ;
Lock lock ;
Condition isFirstShouldExecute;
Condition isSecondShouldExecute;
Synchronizator(boolean isFirstExpected, Lock lock, Condition isFirstShouldExecute, Condition isSecondShouldExecute){
this.isFirstExpected = isFirstExpected;
this.lock =lock;
this.isFirstShouldExecute = isFirstShouldExecute;
this.isSecondShouldExecute = isSecondShouldExecute;
}
}
You can find Condition and ReentrantLock classes useful in this case:
Lock lock = new ReentrantLock();
Condition threadGroup1 = lock.newCondition();
Condition threadGroup2 = lock.newCondition();
volatile boolean isFirstGroupRunning = true;
Pass all four to each thread in both groups. You can actually compose them into new class.
In first thread group use following code:
lock.lock();
try {
while (!isFirstGroupRunning) threadGroup2.await();
// do whatever you need to do in first thread
isFirstGroupRunning = false;
threadGroup1.signal();
} finally {
lock.unlock();
}
In second thread group do similar await / signal sequence:
lock.lock();
try {
while (isFirstGroupRunning) threadGroup1.await();
// do whatever you need to do in second thread
isFirstGroupRunning = true;
threadGroup2.signal();
} finally {
lock.unlock();
}
First, I suggest you not extend Thread nor call the class ThreadGroup1, etc. ThreadGroup is a core class, and there is typically no reason to extend Thread. The best way to handle the logic executed in a thread is to implement Runnable and pass instances of that class to new Thread(myRunnableInstance).
I don't think I understand what you want to really do, but it doesn't sound like threads are the way to go. Threads are meant to run multiple process at the same time, not to do them in a sequence.
It sounds like you might want a different concurrent design, maybe a 'producer consumer model' if you have two separate 'Thread groups' that are acquiring a synchronised block sequentially. In which case you could have both thread groups interacting with the same BlockingQueue. It really depends on what these threads are doing.
See
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/BlockingQueue.html
I want the threads to run in a particular order. Suppose I have three thread T1, T2, T2 .
T1 prints 0
T2 prints 1
T3 prints 2
I want the output in the order 0 1 2, 0 1 2 for certain number of time.
If there are two threads T1 and T2. Printing 0 1, 0 1... can be done using Producer-Consumer Problem using synchronization.
Create a class UnitOfWork:
public class UnitOfWork implements Runnable
{
String text;
public UnitOfWork(String text){
this.text = text;
}
public void run(){
System.out.println(text);
}
}
And then create a single thread executor service:
ExecutorService executor = ExecutorService.newSingleThreadExecutor();
which you will use like this:
UnitOfWork uow0 = new UnitOfWork("0");
UnitOfWork uow1 = new UnitOfWork("1");
UnitOfWork uow2 = new UnitOfWork("2");
for(int i = 0; i < 5; i++){
executor.submit(uow0);
executor.submit(uow1);
executor.submit(uow2);
}
When you are unhappy with the single thread, you can start using multiple thread executor service, which will in fact run tasks concurrently.
Using the method join() in the thread class you can achieve this.
The join method allows one thread to wait for the completion of another. If t is a Thread object whose thread is currently executing,
t.join();
causes the current thread to pause execution until t's thread terminates. Overloads of join allow the programmer to specify a waiting period. However, as with sleep, join is dependent on the OS for timing, so you should not assume that join will wait exactly as long as you specify.
Like sleep, join responds to an interrupt by exiting with an InterruptedException.
Use Thread.join to ensure it terminates before the next thread starts.
public static void main(String[] args) throws InterruptedException {
final Thread th1 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 1");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th2 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 2");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread th3 = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Thread 3");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
th1.start();
th1.join();
th2.start();
th2.join();
th3.start();
}
This is a minimalist piece of code which does literally what you asked for. It relies on the wait-notify mechanism.
I stand by my assesment that you do not need any threads to meet your requirement. A simple loop which prints 0-1-2 is all you really need.
import static java.lang.Thread.currentThread;
public class A {
static int coordinator, timesPrinted;
static final int numThreads = 3, timesToPrint = 300;
public static void main(String[] args) {
for (int i = 0; i < numThreads; i++) {
final int myId = i;
new Thread(new Runnable() { public void run() {
while (true) synchronized (A.class) {
if (coordinator%numThreads == myId) {
System.out.println(myId+1);
coordinator++;
if (timesPrinted++ > timesToPrint) currentThread().interrupt();
A.class.notifyAll();
}
try {A.class.wait();} catch (InterruptedException e) {break;}
}
}}).start();
}
}
}