Threads: How to interrupt a thread from outside of that thread - java

I have a simple GUI in which there are two buttons: Print and Stop.
When the user presses print, an already saved number is printed continuously in a loop.
When the user presses Stop, the printing stops.
I am handling the printing of the number in a separate thread, because I need the thread to sleep for a millisecond before printing again.
printBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Thread a= new Thread(new Runnable(){
public void run(){
textArea.setText("");
for (int i=0; i<10; i++){
int result= 0;
System.out.println(result+"\n");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
a.start();
}
});
Now in the ActionListener of the Stop button, I want the first thread to be interrupted or stopped. How can I do that, since it needs to be interrupted from another thread?

If your first thread contains no Thread-blocking operation, you could for example check for a flag in the for-loop which gets set to true when you press the "Stop"-button.
public class WriterThread implements Runnable {
private volatile boolean stopped = false;
public synchronized void stop() {
this.stopped = true;
}
public void run(){
textArea.setText("");
for (int i=0; i<10; i++) {
if (this.stopped) {
break;
}
int result= 0;
System.out.println(result+"\n");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}

Use AtomicBoolean as flag. It will ensure the thread safety.
Runnable r= new Runnable(){
private AtomicBoolean stop= new AtomicBoolean(false);
public void run(){
for(...){
if(stop.get()){
break; // break the loop
}
...
}
}
public stop(){
stop.set(true);
}
}
Thread a= new Thread(r);
a.start();
r.stop();

final Thread a= new Thread(new Runnable(){
public void run(){
try {
textArea.setText("");
for (int i=0; i<10; i++){
int result= 0;
System.out.println(result+"\n");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
// ignore
}
}
});
printBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
a.start();
}
});
stopBtn.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if( a.isAlive() ) {
a.interrupt();
}
}
});

Related

How do I run 2 Threads alternately

I am new to Threading and I'm trying to make Output look like: aAbBcCdDeE... .
I searched and tried a lot of stuff but nothing really made it work. In the Exercise you are supposed to do it with a global boolean variable but I didn't really find anything useful and am kinda lost. I appreciate the help!
public class ABCThread implements Runnable {
char c;
public ABCThread(char c) {
this.c = c;
}
#Override
public synchronized void run() {
for (char i = 0; i < 26; i++) {
System.out.println(c++);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new ABCThread('a'));
Thread t2 = new Thread(new ABCThread('A'));
t1.start();
t2.start();
}
}
Output:
a
A
B
b
C
c
d
D
e
E
f
F
G
g
H
h
I
i
J
j
Here is the one of the solution to solve the given problem. It uses wait to wait the current thread after printing one letter and notify the other thread to print its letter, and same cycle repeats. The concept of Thread wait and notify is very well explained here.
Short description:
To wait or notify any thread, it (invoking thread) must acquire the lock on any common object. In below example, each thread is acquiring the lock on this (self) (via synchronized run method) to wait and on opponent to notify it (the another thread).
public class App implements Runnable {
char c;
App opponent;
boolean go;
public App(char c, boolean go) {
this.c = c;
this.go = go;
}
public void setOpponent(App opponent) {
this.opponent = opponent;
}
public static void main(String[] args) {
App a = new App('a', true);
App b = new App('A', false);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
a.setOpponent(b);
b.setOpponent(a);
t1.start();
t2.start();
}
#Override
public synchronized void run() {
for (char i = 0; i < 26; i++) {
try {
if (go) {
System.out.println(c++);
this.wait();
synchronized (opponent) {
opponent.notify();
}
} else {
System.out.println(c++);
synchronized (opponent) {
opponent.notify();
}
this.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Here is the more simplified and understandable version of above code. In this code, both the threads are acquiring lock on same lock object, printing the letter, going in WAIT state (so release the lock) and giving turn to other BLOCKED thread waiting for the lock on lock. The other thread then acquires the lock on lock, prints the letter, notifies the previous thread which was waiting on lock object, and goes into WAIT condition, thus releasing the lock.
public class App2 implements Runnable {
char c;
Object lock;
boolean go;
public App2(char c, boolean go) {
this.c = c;
this.go = go;
}
public void setLock(Object lock) {
this.lock = lock;
}
public static void main(String[] args) {
App2 a = new App2('a', true);
App2 b = new App2('A', false);
Thread t1 = new Thread(a);
Thread t2 = new Thread(b);
Object lock = new Object();
a.setLock(lock);
b.setLock(lock);
t1.start();
t2.start();
}
#Override
public void run() {
for (char i = 0; i < 26; i++) {
synchronized (lock) {
try {
if (go) {
System.out.println(c++);
lock.wait();
lock.notify();
} else {
System.out.println(c++);
lock.notify();
lock.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
UPDATE:
Above two approaches will work in most of the cases, but will not guarantee that t1 will be executed before t2 every time. Though t1 is started before t2, but it does not mean that thread scheduler will always pick t1 to execute before t2. To be sure that t1 will execute before t2 in every case, we need to ensure that t2 gets started once t1 is in RUNNABLE state (i.e. running). Below is the one of the way of how we can achieve it:
public class App3 implements Runnable {
char c;
App3 opponent;
boolean go;
boolean createOpponent = false;
public App3(char c, boolean go) {
this.c = c;
this.go = go;
}
public void setOpponent(App3 opponent) {
this.opponent = opponent;
}
public void setCreateOpponent(boolean createOpponent) {
this.createOpponent = createOpponent;
}
public static void main(String[] args) {
App3 a = new App3('a', true);
App3 b = new App3('A', false);
Thread t1 = new Thread(a);
a.setOpponent(b);
a.setCreateOpponent(true);
b.setOpponent(a);
t1.start();
}
#Override
public synchronized void run() {
if (createOpponent) {
setCreateOpponent(false);
new Thread(opponent).start();
}
for (char i = 0; i < 26; i++) {
try {
if (go) {
System.out.println(c++);
this.wait();
synchronized (opponent) {
opponent.notify();
}
} else {
System.out.println(c++);
synchronized (opponent) {
opponent.notify();
}
this.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
You're supposed to use a boolean to control which thread prints:
Thread 1 waits for the boolean to be false. Then it prints and sets it true.
Thread 2 waits for the boolean to be true. Then it prints and sets it false.
In this way, the threads will alternate. Also, all of this will be much faster if you use signaling between threads instead of sleep:
import java.util.*;
import java.lang.*;
import java.io.*;
public class ABCThread implements Runnable {
static Object monitor = new Object();
static boolean turn = false;
char c;
final boolean myTurn;
public ABCThread(char c, boolean myTurn) {
this.c = c;
this.myTurn = myTurn;
}
#Override
public void run() {
for (char i = 0; i < 26; i++) {
synchronized(monitor) {
while (turn != myTurn) {
try {
// Note that the lock is release while I'm waiting,
// So the other thread can claim it here.
monitor.wait();
} catch (Exception e) {
}
}
System.out.println(c++);
turn = !myTurn;
monitor.notifyAll();
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new ABCThread('a', false));
Thread t2 = new Thread(new ABCThread('A', true));
t1.start();
t2.start();
t1.join();
t2.join();
}
}
What you need? A "shared resource" between threads.
Further: A synchronous FSM (Finite state machine)
Below is code that demonstrated how to achieve that.
public class Main
{
// The shared resource
public static class State {
private int val;
private int nStates;
// Init value and number of states.
public State(int init, int nStates) {
this.val = init;
this.nStates = nStates;
}
int get() {
return val;
}
// Define how to get to next state. For simple use case, just increase then modulo it. eg: 0, 1, 0, 1
// Avoid modulo in-case you need very very high performance.
void next() {
this.val = (this.val + 1) % nStates;
}
}
public static class ABCThread implements Runnable{
private char c;
private State s;
private int type;
public ABCThread(char c, State s, int type) {
this.c = c;
this.s = s;
this.type = type;
}
#Override
public void run() {
try {
for (char i = 0; i < 26; i++) {
// Do things synchronously
synchronized(s){
while(s.get() != type) {
// Wait for our turn.
s.wait();
}
System.out.print(c++);
// Update state
s.next();
// Notify to other threads to do their job.
s.notifyAll();
}
}
}catch(Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
// Define the state.
State s = new State(0, 2);
/* Uncomment this block to have 3 synchronous threads. Will print aA1bB2...
s = new State(0, 3);
Thread t3 = new Thread(new ABCThread('1', s, 2));
t3.start();
t3.join();
*/
Thread t1 = new Thread(new ABCThread('a', s, 0));
Thread t2 = new Thread(new ABCThread('A', s, 1));
// Start threads
t1.start();
t2.start();
// Wait for these threads to finish before exit.
t1.join();
t2.join();
}
}
Quick answer:
You can't force a thread to run at a certain moment. What you can do though is let those two run "out of sync" (not related to async coding).
Thread t1 = new Thread(new ABCThread('a'));
Thread.sleep(250);
Thread t2 = new Thread(new ABCThread('A'));
The 1st thread will print about every 500 ms and the 2nd thread will print at 250, 750, 1250, etc.
Note that this would not be a correct way to solve this in real programs. But then again, you would also likely not add Thread.sleep(500) to the run method.
Better:
You need synchronization between the threads. Because you start two threads you can use a boolean.
public class ABCThread implements Runnable {
char c;
static boolean synchronizer = false;
boolean runOn;
public ABCThread(char c, boolean runOn) {
this.c = c;
this.runOn = runOn;
}
#Override
public synchronized void run() {
int count = 0;
while(count < 26)
{
if(runOn != synchronizer)
{
Thread.sleep(100);
continue;
}
count++;
synchronizer = !synchronizer;
System.out.println(c++);
}
}
Thread t1 = new Thread(new ABCThread('a', false));
Thread t2 = new Thread(new ABCThread('A', true));
Just typing this out. It might not compile.
Thread.sleep(100) is just some number. It could possibly be lower, but doesn't matter much for the question.
Even better
The previous code can run with only 2 threads! 1 will just stay stuck with synchronizer = false. If you add a third then the synchronizer won't work because it only has 2 states.
You could add an integer instead of the boolean and another integer amountOfThreads. The amountOfThreads will need to be set to the amount of threads you will start up. Then increase the atomic integer when the thread prints and if the synchronizer (the atomic int) is more than amountOfThreads, set it to 0.
Hope this helps...
public class ABCThread implements Runnable {
char c;
boolean flag;
public ABCThread(char c, boolean flag) {
this.c = c;
this.flag = flag;
}
#Override
public synchronized void run() {
for (char i = 0; i < 52; i++) {
try {
if (flag) {
System.out.println(c++);
notifyAll();
flag = false;
wait(100);
} else {
flag = true;
wait(100);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new ABCThread('a', true));
Thread t2 = new Thread(new ABCThread('A', false));
t1.start();
t2.start();
}
}
or you can define separate methods for printing small and capital letters and run them in two separate threads
public class ABCThread {
boolean flag;
public ABCThread(boolean flag) {
this.flag = flag;
}
public static void main(String[] args) throws InterruptedException {
ABCThread abc = new ABCThread(false);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
try {
abc.printSmallLetters();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread t2 = new Thread(new Runnable() {
public void run() {
try {
abc.printCapitalLetters();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
t1.start();
t2.start();
}
synchronized void printSmallLetters() throws InterruptedException {
for (char i = 'a'; i < 'z'; i++) {
while (flag == true) {
wait();
}
System.out.println(i);
notifyAll();
flag = true;
}
}
synchronized void printCapitalLetters() throws InterruptedException {
for (char i = 'A'; i < 'Z'; i++) {
while (flag == false) {
wait();
}
System.out.println(i);
notifyAll();
flag = false;
}
}
}
just replace the println by print to get a series output like this
other than that everything seems to be fine,
you can see the output i got in the screenshot above
No way. The order of execution of threads cannot be controlled).You can use Thread.yield(). But yield () - tries to tell the scheduler to execute the next thread, but it stays in the RUNNABLE state.

What would be the consequences of running several threads like this?

I need to run 2 threads simultaneously (on occasion if both have been requested together) otherwise if either one is requested solo then each thread needs to run on its own. Each thread will be responsible for taking its own unique reading from its own unique transducer (actual hardware), I need each thread to query its transducer until a certain value is detected. If and only if this value is detected should the thread stop and exit.
I also need a way for my software to know without a doubt that both threads have stopped and exited/completed their task and detected their respective values from the hardware. If and only if both threads detect their values should my onFinish() method be called. In my code, I used a third thread to do this monitoring and the use of integer values. The integer variable threadCount is reset to 0 once my onFinish() method is called and so is my boolean shouldRun which is reset to false within the onFinish() method.
Was wondering if my approach is acceptable/sound logically ( please note I havent done the logic yet for the actual query of each transducer (likely will use a while loop)) also what are the consequences for using the approach I described, my code is as seen below:
private void decreaseThreadCount(){
threadCount -=1;
}
boolean shouldRun = false;
int threadCount = 0;
public void onStart() {
System.out.println("START");
System.out.println(" ");
System.out.println("START PROGRESS BAR");
if((customProgressBarL != null || customProgressBarR != null) || (customProgressBarL != null && customProgressBarR != null)){
shouldRun = true;
}
/**TESTING PURPOSES*/
if (customProgressBarL != null) {
threadCount += 1;
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 100; i++) {
try {
customProgressBarL.updateProgress(i);
customProgressBarL.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(5);
decreaseThreadCount();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
if (customProgressBarR != null) {
threadCount += 1;
new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i <= 100; i++) {
try {
customProgressBarR.updateProgress(i);
customProgressBarR.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.out.println("Thread Count: " + threadCount);
try {
Thread.sleep(5);
decreaseThreadCount();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
new Thread(new Runnable() {
#Override
public void run() {
while(threadCount >= 0 && shouldRun){
try {
System.out.println("Thread Count: " + threadCount);
if(threadCount == 0){
onFinish();
return;
}
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
return;
}
}).start();
}
[Edit 1] After reading through the advice given and a bunch of online documentation I have come up with the following code which seems to work under the cases I have tested so far.
Was wondering if I should still use SwingWorkers or if the modified approach is acceptable?
public void onStart() {
System.out.println("START");
System.out.println(" ");
System.out.println("START PROGRESS BAR");
/**TESTING PURPOSES*/
CountDownLatch countDownLatch = new CountDownLatch(2);
new Thread(new Runnable() {
#Override
public void run() {
new Thread(new Runnable() {
#Override
public void run() {
if (customProgressBarL != null) {
for (int i = 0; i <= 100; i++) {
try {
customProgressBarL.updateProgress(i);
customProgressBarL.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
countDownLatch.countDown();
return;
}
}).start();
new Thread(new Runnable() {
#Override
public void run() {
if(customProgressBarR != null){
for (int i = 0; i <= 100; i++) {
try {
customProgressBarR.updateProgress(i);
customProgressBarR.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
countDownLatch.countDown();
return;
}
}).start();
try{
countDownLatch.await();
onFinish();
} catch (InterruptedException e){
e.printStackTrace();
}
}
}).start();
}
[Edit 2]
I have tried a version where I use SwingWorker instead of my Threads, below is the code and it works just as well as the code in [Edit 1] (as far as I can tell at least). What are the pros/cons of each approach?
private class MySwingWorker extends SwingWorker<Object, Object> {
CountDownLatch countDownLatch;
JCustomProgressBar progressBar;
public MySwingWorker(CountDownLatch countDownLatch, JCustomProgressBar progressBar){
this.countDownLatch = countDownLatch;
this.progressBar = progressBar;
}
#Override
protected Object doInBackground() throws Exception {
if(progressBar != null){
for (int i = 0; i <= 100; i++) {
try {
progressBar.updateProgress(i);
progressBar.repaint();
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
countDownLatch.countDown();
return null;
}
}
private class MySwingWorkerManager extends SwingWorker<Object, Object> {
CountDownLatch countDownLatch;
#Override
protected Object doInBackground() throws Exception {
this.countDownLatch = new CountDownLatch(2);
new MySwingWorker(countDownLatch, customProgressBarL).execute();
new MySwingWorker(countDownLatch, customProgressBarR).execute();
try{
countDownLatch.await();
onFinish();
} catch (InterruptedException e){
e.printStackTrace();
}
return null;
}
}
I initiate everything as follows in my onStart() method by calling the execute() method:
public void onStart() {
System.out.println("START");
System.out.println(" ");
System.out.println("START PROGRESS BAR");
System.out.println("customProgressBarL is: "+customProgressBarL);
System.out.println("customProgressBarR is: "+customProgressBarR);
/**TESTING PURPOSES*/
new MySwingWorkerManager().execute();
}
You've initiated all the threads simultanesouly outside (T1,T2,T3) and T3 is waiting for all of them to finish and do some onFinish.
Instead you can instantiate T1 and T2 inside T3.
Create a countdown latch with the number of count.
Decrement the latch count when both the threads finish their task and then execute onFinish().
All the logic to create T1/T2 should be inside T3.
new Thread(new Runnable() {
#Override
public void run() {
int count = 2;
CountdownLatch latch = new CountdownLatch(count);
MyThread t1 = new MyThread(latch);
MyThread t2 = new MyThread(latch);
t1.start()
t2.start();
latch.await();
onFinish();
}
}).start();
Only one thread is supposed to access swing components; you should write something like that:
SwingUtilities.invokeLater(() -> {
customProgressBarR.updateProgress(i);
customProgressBarR.repaint();
});

How to run while loops in different threads? [duplicate]

I got asked this question recently in an interview.
Write a program with two threads (A and B), where A prints 1 , B prints 2 and so on until 50 is reached.
How do we go about doing that ?
The essence of the assignment is to demonstrate how a thread can signal another one. Most common way is to use blocking queues, but here a signal does not carry any information, so a Semaphore is sufficient.
Create thread class which is parameterized with 2 Semaphores: input and output:
class ThreadPrinter implements Runnable {
int counter;
Semaphore ins, outs;
ThreadPrinter(int counter, Semaphore ins, Semaphore outs) {
this.counter = counter;
this.ins = ins;
this.outs = outs;
}
#Override
public void run() {
for (int i = 0; i < 25; i++) {
ins.aquire(); // wait for permission to run
System.out.println("" + counter);
outs.release(); // allow another thread to run
counter += 2;
}
}
Create 2 Semaphores and pass them to 2 threads:
Semaphore a = new Semaphore(1); // first thread is allowed to run immediately
Semaphore b = new Semaphore(0); // second thread has to wait
ThreadPrinter tp1 = new ThreadPrinter(1, a, b);
ThreadPrinter tp2 = new ThreadPrinter(2, b, a);
Note semaphores a and b are passed in different order.
public class Test {
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 25; i++) {
synchronized (CommonUtil.mLock) {
incrementCount();
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 25; i++) {
synchronized (CommonUtil.mLock) {
incrementCount();
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
t1.start();
Thread.sleep(400);
t2.start();
t1.join();
t2.join();
}
private static void incrementCount() {
count++;
System.out.println("Count: " + count + " icnremented by: " + Thread.currentThread().getName());
}
}
class CommonUtil {
static final Object mLock = new Object();
}
I encountered the same problem and was expected to use only basics so I choose wait notify on shared object between threads
public class Message implements Runnable {
private static final int N = 10;
private Thread thread;
private static Object object = new Object();
public Message(String name){
thread = new Thread(this, name);
thread.start();
}
public void run(){
for(int i=0; i<N; i++){
synchronized (object) {
System.out.println(i + "--" + thread.getName());
object.notify();
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
In main method :
Message message1 = new Message("Ping");
Message message2 = new Message("Pong");
public class ThreadCounter implements Runnable {
private static int count = 0;
private Thread t;
public ThreadCounter(String tName){
t= new Thread(this, tName);
t.start();
}
#Override
public void run() {
for(int i=1; i<=5; i++){
synchronized (CommonUtil.mLock) {
incrementCount(t.getName());
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void incrementCount(String tName){
System.out.println(tName+": "+(++ThreadCounter.count));
}
public static void main(String[] args) throws InterruptedException {
new ThreadCounter("Thread1");
Thread.sleep(500);
new ThreadCounter("Thread2");
}
}
class CommonUtil{
public static Object mLock = new Object();
}
hi please find answer here...pattern ABABABAB
package com.abhi.ThreadPractice;
public class Test {
public static void main(String[] args) throws InterruptedException {
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
// count++;
System.out.println("A");
try {
lock.wait();
lock.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
lock.notify();
//count++;
System.out.println("B");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
This is another solution:
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
for (int i = 1; i <= 50; i += 2) {
System.out.println("T1=" + i);
t1turn = false;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
for (int i = 2; i <= 50; i += 2) {
if (t1turn)
try {
lock.wait();
} catch (InterruptedException e) {
}
System.out.println("T2=" + i);
t1turn = true;
lock.notify();
}
}
}
});
t1.start();
t2.start();
May be this is still relevant:
public class MyRunnable implements Runnable {
public static int counter = 0;
public static int turn = 0;
public static Object lock = new Object();
#Override
public void run() {
while (counter < 50) {
synchronized (lock) {
if (turn == 0) {
System.out.println(counter + " from thread "
+ Thread.currentThread().getName());
turn = 1;
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
} else {
turn = 0;
lock.notify();
}
}
}
}
}
and then the main function
public static void main(String[] args) {
Thread threadA = new Thread(new MyRunnable());
Thread threadB = new Thread(new MyRunnable ());
threadA.start();
threadB.start();
}
public class PingPong extends Thread {
static StringBuilder object = new StringBuilder("");
public static void main(String[] args) throws InterruptedException {
Thread t1 = new PingPong();
Thread t2 = new PingPong();
t1.setName("\nping");
t2.setName(" pong");
t1.start();
t2.start();
}
#Override
public void run() {
working();
}
void working() {
while (true) {
synchronized (object) {
try {
System.out.print(Thread.currentThread().getName());
object.notify();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
This was the simplest solution, I was able to think of. It uses a synchronized method and uses the notify() and the wait() to alternatively print the numbers. Hope it helps. :)
public class program implements Runnable
{
static int count =1;
private static final int MAX_COUNT = 50;
public synchronized void print ()
{
System.out.println(Thread.currentThread().getName() + " is printing " + count);
count++;
notify();
try{
if(count>MAX_COUNT)
return;
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void run()
{
for(int i=0;i<MAX_COUNT/2;i++)
{
print();
}
}
public static void main(String[] args) {
program x= new program();
Thread t0= new Thread(x);
Thread t1= new Thread(x);
t0.start();
try
{
Thread.sleep(1);
} catch (InterruptedException e){
e.printStackTrace();
}
t1.start();
}
}
//simply use wait and notify and and set a counter and it will do
public class ThreadalternatePrint implements Runnable {
static int counter =0;
#Override
public synchronized void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(counter<51)
{ ++counter;
notify();
System.out.println(Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadalternatePrint obj1 = new ThreadalternatePrint();
Thread Th1 = new Thread(obj1);
Thread Th2 = new Thread(obj1);
Th1.setName("Thread1");
Th2.setName("Thread2");
Th1.start();
Th2.start();
}
}
public class Testing implements Runnable {
private static int counter = 1;
private static final Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Testing(), "1");
t1.start();
Thread t2 = new Thread(new Testing(), "2");
t2.start();
}
#Override
public void run() {
while (counter<=100) {
synchronized (lock) {
if (counter % 2 == 0) {
System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
counter++;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (counter % 2 == 1) {
System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
counter++;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
I have created a pretty basic Solution for it using the Reentrant Lock.
package com.multithreding.trylock;
import java.util.concurrent.locks.ReentrantLock;
public class TryLock extends Thread {
static int intitialCount = 50; //Value till which you want to print
int valueToSubtract = 0; //Value by which difference you want to print the series like 1,2,3
static ReentrantLock alternate = new ReentrantLock();
public TryLock(String name) {
this.setName(name);
}
public void run() {
while (intitialCount > 1) {
if (valueToSubtract > 0) {
alternate.lock();
intitialCount = intitialCount - valueToSubtract;
valueToSubtract = 0;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("value Subtracted " + intitialCount + " by the Thread" + this.getName());
alternate.unlock();
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
valueToSubtract++;
}
}
}
}
package com.multithreding.trylock;
public class AlternatePrint {
public static void main(String[] args) throws InterruptedException{
//You can add as many thread to print then in different number of series
TryLock t1 = new TryLock("Odd One");
TryLock t2 = new TryLock("Even Value");
t1.start();
t2.start();
}
}
This solution is modular as well,
You can add 'n' number of Threads to print the alternate series. i.e Using 3 thread at once
You can also print the series with more than Difference of more than 1. i.e 1,3,5 etc
package thread;
public class Pingpong extends Thread {
static StringBuilder object = new StringBuilder("");
static int i=1;
#Override
public void run() {
working();
}
void working() {
while (i<=10) {
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName() +" "+ i);
i++;
object.notify();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Pingpong();
Thread t2 = new Pingpong();
t1.setName("Thread1");
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Thread1 1
Thread2 2
Thread1 3
Thread2 4
Thread1 5
Thread2 6
Thread1 7
Thread2 8
Thread1 9
Thread2 10
This answer is generic i.e. not only to print numbers alternately from 2 threads but to execute 2 threads alternately.
The above approaches are commendable but this one doesn't need any lock but instead it uses an AtomicInteger variable alongwith 2 AtomicBooleans to indicate when one thread has finished executing so that the other can finish executing the rest of its remaining execution.
This will work in all 3 cases:
When number of executions of both threads are same.
When first thread finishes before second thread and second thread has more number of executions than first thread.
When second thread finishes before first thread and first thread has more number of executions than second thread.
public class TestAlternateExecutionOfTwoThreads
{
private static final AtomicInteger count = new AtomicInteger(0);
private static final AtomicBoolean firstIsDone = new AtomicBoolean(false);
private static final AtomicBoolean secondIsDone = new AtomicBoolean(false);
// change the below values to change the number of iterations each thread should
// run. In this example, the initial value are hard-coded but you can change
// them as well.
private static final int finalOfFirstThread = 10;
private static final int finalOfSecondThread = 109;
public static void main(String[] args)
{
Runnable r1 = () -> {
int i = 1;
for(; i <= finalOfFirstThread; )
{
while(count.get() == 0)
{
System.out.println(i);
count.incrementAndGet();
i++;
}
if(count.get() == 1 && secondIsDone.get() && i != (finalOfFirstThread + 1))
{
System.out.println(i);
i++;
}
}
firstIsDone.set(true);
};
Runnable r2 = () -> {
int j = 100;
for (; j <= finalOfSecondThread; )
{
while(count.get() == 1)
{
System.out.println(j);
count.decrementAndGet();
j++;
}
if(count.get() == 0 && firstIsDone.get() && j != (finalOfSecondThread + 1))
{
System.out.println(j);
j++;
}
}
secondIsDone.set(true);
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
I guess this might help.
Although it is not standard but i hope it provides a simpler approach.
public class ThreadDemo
{
public static void main (String [] args)
{
PrintDemo pd=new PrintDemo();
MyThread1 mt1 = new MyThread1 ("T1",pd);
MyThread2 mt2 = new MyThread2 ("T2",pd);
mt1.start ();
mt2.start();
}
}
class PrintDemo {
private boolean oddFlag=true;
public synchronized void printOdd(int i,String tName){
if(oddFlag==false){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("\nThread "+tName+" count:"+i);
oddFlag=false;
notify();
}
}
public synchronized void printEven(int i,String tName){
if(oddFlag==true){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("\nThread "+tName+" count:"+i);
oddFlag=true;
notify();
}
}
}
class MyThread1 extends Thread
{
private PrintDemo pd;
private String name;
MyThread1(String threadName,PrintDemo pd){
this.name=threadName;
this.pd=pd;
}
public void run ()
{
for(int i=1;i<=50;i+=2){
pd.printOdd(i,name);
}
}
}
class MyThread2 extends Thread
{
private PrintDemo pd;
private String name;
MyThread2(String threadName,PrintDemo pd){
this.name=threadName;
this.pd=pd;
}
public void run ()
{
for(int i=2;i<=50;i+=2){
pd.printEven(i,name);
}
}
}

Run a method on specific thread given the thread id

If i know a specific thread id. How to do the following?
Thread.getThreadById(id).continueWork();
Is it possible?
public class Test implements Runnable {
public void run() {
while(true){
pause();
doSomework();
}
}
private void doSomework() {
System.out.println("do some work");
}
public synchronized void pause() {
if (Tester.waitCondition == true) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void continueWork() {
notify();
}
}
public class Tester {
public static boolean waitCondition = true;
public static void main(String[] args) {
Thread nThread = new Thread(new Test());
nThread.start();
waitCondition = false;
Thread nThread1 = new Thread(new Test());
nThread1.start();
Thread nThread2 = new Thread(new Test());
nThread2.start();
Thread nThread3 = new Thread(new Test());
nThread3.start();
Long id = nThread.getId();
Thread.getThreadById(id).continueWork();
}
}
You need block the thread with a lock , then call the lock's notify method to set blocked thread runnable .
If more than one thread to be continued , you will need Condition .
Like blow:
final Lock lock = new ReentrantLock();
final Condition condition1 = lock.newCondition();
final Condition condition2 = lock.newCondition();
Thread t = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition1.await();
System.out.println("end cdt1");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
t.start();
Thread t1 = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition2.await();
System.out.println("end cdt2");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
t1.start();
Thread.sleep(1000);
Thread tt = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition1.signal();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
tt.start();
Thread.sleep(2000);
Thread tt1 = new Thread() {
#Override
public void run() {
try {
lock.lock();
condition2.signal();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.unlock();
}
}
};
tt1.start();
Elaborating:
public class Tester {
// Apologies, I'm too lazy to create two separate files
static public class Test implements Runnable {
private void doSomework() {
System.out.print(
"do some work on Thread: "
+Thread.currentThread().getId()
);
try {
Thread.sleep(500); // just to simulate a load
}
catch(InterruptedException e) {
// ignore
}
}
public void run() {
do {
boolean shouldIWait=true;
synchronized(Tester.lockingObj) {
Boolean flag=Tester.waitConditions.get(Thread.currentThread().getId());
if(null!=flag) {
shouldIWait=flag.booleanValue();
} // if null, the tester started me before creating my flag. I'll wait
if(shouldIWait) {
// I need to wait for someone to wake me
try {
Tester.lockingObj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
// well, I'm interrupted, so I'll do no more work.
break;
}
}
}
if(false==shouldIWait) {
// waiting no more
this.doSomework();
}
} while(true);
}
}
public static Object lockingObj=new Object();
public static TreeMap<Long, Boolean> waitConditions=
new TreeMap<Long, Boolean>();
public static void main(String[] args) {
Thread nThread = new Thread(new Test());
Thread nThread1 = new Thread(new Test());
Thread nThread2 = new Thread(new Test());
Thread nThread3 = new Thread(new Test());
// when starting, all threads will be waiting
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
waitConditions.put(nThread.getId(), true);
nThread2.start();
nThread1.start();
nThread.start();
nThread3.start();
Long id = nThread.getId();
synchronized (lockingObj) { // when notified, all thread should wakeup
waitConditions.put(id, false); // but only nThread will be allowed to doSomeWork
lockingObj.notifyAll(); // wake up all the threads.
// Those not allowed, will go into
// back waiting
}
try {
// just to have the main thread still running for a while
Thread.sleep(3000);
} catch (InterruptedException e) {
}
// maybe we want to switch of nThread and start another?
synchronized (lockingObj) {
waitConditions.put(id, true);
waitConditions.put(nThread1.getId(), false);
lockingObj.notifyAll();
}
try {
// just to have the main thread still running for a while
Thread.sleep(3000);
} catch (InterruptedException e) {
}
}
}

Writing a program with 2 threads which prints alternatively

I got asked this question recently in an interview.
Write a program with two threads (A and B), where A prints 1 , B prints 2 and so on until 50 is reached.
How do we go about doing that ?
The essence of the assignment is to demonstrate how a thread can signal another one. Most common way is to use blocking queues, but here a signal does not carry any information, so a Semaphore is sufficient.
Create thread class which is parameterized with 2 Semaphores: input and output:
class ThreadPrinter implements Runnable {
int counter;
Semaphore ins, outs;
ThreadPrinter(int counter, Semaphore ins, Semaphore outs) {
this.counter = counter;
this.ins = ins;
this.outs = outs;
}
#Override
public void run() {
for (int i = 0; i < 25; i++) {
ins.aquire(); // wait for permission to run
System.out.println("" + counter);
outs.release(); // allow another thread to run
counter += 2;
}
}
Create 2 Semaphores and pass them to 2 threads:
Semaphore a = new Semaphore(1); // first thread is allowed to run immediately
Semaphore b = new Semaphore(0); // second thread has to wait
ThreadPrinter tp1 = new ThreadPrinter(1, a, b);
ThreadPrinter tp2 = new ThreadPrinter(2, b, a);
Note semaphores a and b are passed in different order.
public class Test {
private static int count = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 25; i++) {
synchronized (CommonUtil.mLock) {
incrementCount();
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 25; i++) {
synchronized (CommonUtil.mLock) {
incrementCount();
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
});
t1.start();
Thread.sleep(400);
t2.start();
t1.join();
t2.join();
}
private static void incrementCount() {
count++;
System.out.println("Count: " + count + " icnremented by: " + Thread.currentThread().getName());
}
}
class CommonUtil {
static final Object mLock = new Object();
}
I encountered the same problem and was expected to use only basics so I choose wait notify on shared object between threads
public class Message implements Runnable {
private static final int N = 10;
private Thread thread;
private static Object object = new Object();
public Message(String name){
thread = new Thread(this, name);
thread.start();
}
public void run(){
for(int i=0; i<N; i++){
synchronized (object) {
System.out.println(i + "--" + thread.getName());
object.notify();
try {
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
In main method :
Message message1 = new Message("Ping");
Message message2 = new Message("Pong");
public class ThreadCounter implements Runnable {
private static int count = 0;
private Thread t;
public ThreadCounter(String tName){
t= new Thread(this, tName);
t.start();
}
#Override
public void run() {
for(int i=1; i<=5; i++){
synchronized (CommonUtil.mLock) {
incrementCount(t.getName());
CommonUtil.mLock.notify();
try {
CommonUtil.mLock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private void incrementCount(String tName){
System.out.println(tName+": "+(++ThreadCounter.count));
}
public static void main(String[] args) throws InterruptedException {
new ThreadCounter("Thread1");
Thread.sleep(500);
new ThreadCounter("Thread2");
}
}
class CommonUtil{
public static Object mLock = new Object();
}
hi please find answer here...pattern ABABABAB
package com.abhi.ThreadPractice;
public class Test {
public static void main(String[] args) throws InterruptedException {
final Object lock = new Object();
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
// count++;
System.out.println("A");
try {
lock.wait();
lock.notify();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
synchronized (lock) {
lock.notify();
//count++;
System.out.println("B");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
t1.start();
t2.start();
t1.join();
t2.join();
}
}
This is another solution:
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
for (int i = 1; i <= 50; i += 2) {
System.out.println("T1=" + i);
t1turn = false;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
}
}
}
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
synchronized (lock) {
for (int i = 2; i <= 50; i += 2) {
if (t1turn)
try {
lock.wait();
} catch (InterruptedException e) {
}
System.out.println("T2=" + i);
t1turn = true;
lock.notify();
}
}
}
});
t1.start();
t2.start();
May be this is still relevant:
public class MyRunnable implements Runnable {
public static int counter = 0;
public static int turn = 0;
public static Object lock = new Object();
#Override
public void run() {
while (counter < 50) {
synchronized (lock) {
if (turn == 0) {
System.out.println(counter + " from thread "
+ Thread.currentThread().getName());
turn = 1;
try {
lock.wait();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
} else {
turn = 0;
lock.notify();
}
}
}
}
}
and then the main function
public static void main(String[] args) {
Thread threadA = new Thread(new MyRunnable());
Thread threadB = new Thread(new MyRunnable ());
threadA.start();
threadB.start();
}
public class PingPong extends Thread {
static StringBuilder object = new StringBuilder("");
public static void main(String[] args) throws InterruptedException {
Thread t1 = new PingPong();
Thread t2 = new PingPong();
t1.setName("\nping");
t2.setName(" pong");
t1.start();
t2.start();
}
#Override
public void run() {
working();
}
void working() {
while (true) {
synchronized (object) {
try {
System.out.print(Thread.currentThread().getName());
object.notify();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
This was the simplest solution, I was able to think of. It uses a synchronized method and uses the notify() and the wait() to alternatively print the numbers. Hope it helps. :)
public class program implements Runnable
{
static int count =1;
private static final int MAX_COUNT = 50;
public synchronized void print ()
{
System.out.println(Thread.currentThread().getName() + " is printing " + count);
count++;
notify();
try{
if(count>MAX_COUNT)
return;
wait();
}catch (InterruptedException e){
e.printStackTrace();
}
}
public void run()
{
for(int i=0;i<MAX_COUNT/2;i++)
{
print();
}
}
public static void main(String[] args) {
program x= new program();
Thread t0= new Thread(x);
Thread t1= new Thread(x);
t0.start();
try
{
Thread.sleep(1);
} catch (InterruptedException e){
e.printStackTrace();
}
t1.start();
}
}
//simply use wait and notify and and set a counter and it will do
public class ThreadalternatePrint implements Runnable {
static int counter =0;
#Override
public synchronized void run() {
try {
Thread.sleep(10);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
while(counter<51)
{ ++counter;
notify();
System.out.println(Thread.currentThread().getName());
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ThreadalternatePrint obj1 = new ThreadalternatePrint();
Thread Th1 = new Thread(obj1);
Thread Th2 = new Thread(obj1);
Th1.setName("Thread1");
Th2.setName("Thread2");
Th1.start();
Th2.start();
}
}
public class Testing implements Runnable {
private static int counter = 1;
private static final Object lock = new Object();
public static void main(String[] args) {
Thread t1 = new Thread(new Testing(), "1");
t1.start();
Thread t2 = new Thread(new Testing(), "2");
t2.start();
}
#Override
public void run() {
while (counter<=100) {
synchronized (lock) {
if (counter % 2 == 0) {
System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
counter++;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
} else if (counter % 2 == 1) {
System.out.println(counter +" Written By Thread-"+ Thread.currentThread().getName());
counter++;
try {
lock.notifyAll();
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
I have created a pretty basic Solution for it using the Reentrant Lock.
package com.multithreding.trylock;
import java.util.concurrent.locks.ReentrantLock;
public class TryLock extends Thread {
static int intitialCount = 50; //Value till which you want to print
int valueToSubtract = 0; //Value by which difference you want to print the series like 1,2,3
static ReentrantLock alternate = new ReentrantLock();
public TryLock(String name) {
this.setName(name);
}
public void run() {
while (intitialCount > 1) {
if (valueToSubtract > 0) {
alternate.lock();
intitialCount = intitialCount - valueToSubtract;
valueToSubtract = 0;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("value Subtracted " + intitialCount + " by the Thread" + this.getName());
alternate.unlock();
} else {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
valueToSubtract++;
}
}
}
}
package com.multithreding.trylock;
public class AlternatePrint {
public static void main(String[] args) throws InterruptedException{
//You can add as many thread to print then in different number of series
TryLock t1 = new TryLock("Odd One");
TryLock t2 = new TryLock("Even Value");
t1.start();
t2.start();
}
}
This solution is modular as well,
You can add 'n' number of Threads to print the alternate series. i.e Using 3 thread at once
You can also print the series with more than Difference of more than 1. i.e 1,3,5 etc
package thread;
public class Pingpong extends Thread {
static StringBuilder object = new StringBuilder("");
static int i=1;
#Override
public void run() {
working();
}
void working() {
while (i<=10) {
synchronized (object) {
try {
System.out.println(Thread.currentThread().getName() +" "+ i);
i++;
object.notify();
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Pingpong();
Thread t2 = new Pingpong();
t1.setName("Thread1");
t2.setName("Thread2");
t1.start();
t2.start();
}
}
Thread1 1
Thread2 2
Thread1 3
Thread2 4
Thread1 5
Thread2 6
Thread1 7
Thread2 8
Thread1 9
Thread2 10
This answer is generic i.e. not only to print numbers alternately from 2 threads but to execute 2 threads alternately.
The above approaches are commendable but this one doesn't need any lock but instead it uses an AtomicInteger variable alongwith 2 AtomicBooleans to indicate when one thread has finished executing so that the other can finish executing the rest of its remaining execution.
This will work in all 3 cases:
When number of executions of both threads are same.
When first thread finishes before second thread and second thread has more number of executions than first thread.
When second thread finishes before first thread and first thread has more number of executions than second thread.
public class TestAlternateExecutionOfTwoThreads
{
private static final AtomicInteger count = new AtomicInteger(0);
private static final AtomicBoolean firstIsDone = new AtomicBoolean(false);
private static final AtomicBoolean secondIsDone = new AtomicBoolean(false);
// change the below values to change the number of iterations each thread should
// run. In this example, the initial value are hard-coded but you can change
// them as well.
private static final int finalOfFirstThread = 10;
private static final int finalOfSecondThread = 109;
public static void main(String[] args)
{
Runnable r1 = () -> {
int i = 1;
for(; i <= finalOfFirstThread; )
{
while(count.get() == 0)
{
System.out.println(i);
count.incrementAndGet();
i++;
}
if(count.get() == 1 && secondIsDone.get() && i != (finalOfFirstThread + 1))
{
System.out.println(i);
i++;
}
}
firstIsDone.set(true);
};
Runnable r2 = () -> {
int j = 100;
for (; j <= finalOfSecondThread; )
{
while(count.get() == 1)
{
System.out.println(j);
count.decrementAndGet();
j++;
}
if(count.get() == 0 && firstIsDone.get() && j != (finalOfSecondThread + 1))
{
System.out.println(j);
j++;
}
}
secondIsDone.set(true);
};
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
I guess this might help.
Although it is not standard but i hope it provides a simpler approach.
public class ThreadDemo
{
public static void main (String [] args)
{
PrintDemo pd=new PrintDemo();
MyThread1 mt1 = new MyThread1 ("T1",pd);
MyThread2 mt2 = new MyThread2 ("T2",pd);
mt1.start ();
mt2.start();
}
}
class PrintDemo {
private boolean oddFlag=true;
public synchronized void printOdd(int i,String tName){
if(oddFlag==false){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("\nThread "+tName+" count:"+i);
oddFlag=false;
notify();
}
}
public synchronized void printEven(int i,String tName){
if(oddFlag==true){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("\nThread "+tName+" count:"+i);
oddFlag=true;
notify();
}
}
}
class MyThread1 extends Thread
{
private PrintDemo pd;
private String name;
MyThread1(String threadName,PrintDemo pd){
this.name=threadName;
this.pd=pd;
}
public void run ()
{
for(int i=1;i<=50;i+=2){
pd.printOdd(i,name);
}
}
}
class MyThread2 extends Thread
{
private PrintDemo pd;
private String name;
MyThread2(String threadName,PrintDemo pd){
this.name=threadName;
this.pd=pd;
}
public void run ()
{
for(int i=2;i<=50;i+=2){
pd.printEven(i,name);
}
}
}

Categories