Related
How can I make the callback execute in the "main thread"?
#Test
void threadTest() throws InterruptedException {
System.out.println("main thread:" + Thread.currentThread());
new Thread(new AsyncTask(this::callback)).start();
Thread.sleep(1100);
}
private void callback() {
System.out.println("callback executed in: " + Thread.currentThread());
}
static class AsyncTask implements Runnable{
private final Runnable runnable;
public AsyncTask(Runnable runnable) {
this.runnable = runnable;
}
#Override
public void run() {
System.out.println("other thread: " + Thread.currentThread());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
this.runnable.run();
}
}
You could try to force execution of callback() in particular ExecutorService:
class ConcTest {
ExecutorService mainExecutor = Executors.newFixedThreadPool(1);
#Test
void threadTest() throws Exception {
mainExecutor.submit(() -> {
System.out.println("main thread:" + Thread.currentThread());
new Thread(new AsyncTask(mainExecutor, this::callback)).start();
sleep(1100);
}).get();
}
private void callback() {
System.out.println("callback executed in: " + Thread.currentThread());
}
private static void sleep(int millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
static class AsyncTask implements Runnable{
private final ExecutorService mainExecutor;
private final Runnable runnable;
public AsyncTask(ExecutorService mainExecutor, Runnable runnable) {
this.mainExecutor = mainExecutor;
this.runnable = runnable;
}
#Override
public void run() {
System.out.println("other thread: " + Thread.currentThread());
try {
Thread.sleep(1000);
mainExecutor.submit(runnable).get();
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
}
This prints
main thread:Thread[pool-1-thread-1,5,main]
other thread: Thread[Thread-0,5,main]
callback executed in: Thread[pool-1-thread-1,5,main]
I am running two variations of similar code, expecting same result to appear however the output shows unexpected results.
variation1 with Synchronized block
public class SomeTask implements Runnable {
public int count = 0;
#Override
public void run() {
synchronized (this) {
for (int i = 0; i < 1_000_000; i++) {
count++;
}
}
}
}
public class TestMemory {
public static void main(String[] args) {
SomeTask task1 = new SomeTask();
Thread t1 = new Thread(task1);
Thread t2 = new Thread(task1);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main Thread Executed");
System.out.println(Thread.currentThread().getName() + ": " + task1.count);
}
}
output
Main Thread Executed
main: 2000000
no matter how many times we run
variation2 with ReentrantLock
public class SomeTask implements Runnable {
public int count = 0;
#Override
public void run() {
Lock lock = new ReentrantLock();
try {
lock.lock();
for (int i = 0; i < 1_000_000; i++) {
count++;
}
} finally {
lock.unlock();
}
}
}
public class TestMemory {
public static void main(String[] args) {
SomeTask task1 = new SomeTask();
SomeTask task2 = new SomeTask();
Thread t1 = new Thread(task1);
Thread t2 = new Thread(task1);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main Thread Executed");
System.out.println(Thread.currentThread().getName() + ": " + task1.count);
}
}
output
Main Thread Executed
main: 1023239
changes the value in multiple executions
Conclusion
Expected result is 2000000 in both the cases, however only synchronized block is working as expected.
Ah my bad I was using two different object of ReentrantLock
Modified Code
public class TestMemory {
public static void main(String[] args) {
Lock lock = new ReentrantLock();
SomeTask task1 = new SomeTask(lock);
SomeTask task2 = new SomeTask(lock);
Thread t1 = new Thread(task1);
Thread t2 = new Thread(task1);
t1.start();
t2.start();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main Thread Executed");
System.out.println(Thread.currentThread().getName() + ": " + task1.count);
}
}
----------
public class SomeTask implements Runnable {
public int count = 0;
Lock lock;
public SomeTask(Lock lock) {
this.lock = lock;
// TODO Auto-generated constructor stub
}
#Override
public void run() {
try {
lock.lock();
for (int i = 0; i < 1_000_000; i++) {
count++;
}
} finally {
lock.unlock();
}
}
}
Output
Main Thread Executed
main: 2000000
This is a problem I have always heard about in school but never had a reason to mess with until I was asked for an interview.
Prompt: Using 2 threads print "Thread i: The number is 'j'" in order where j = 1:100 and i is the thread number. Thread 1 can only print odd j's and Thread 2 can only print even j's.
EDIT the output of j must be ordered
This was my attempt but I did not move on in the interview process. Is there any fundamental part I am missing? Are there any optimizations?
import java.util.concurrent.Semaphore;
public class ThreadSynchronization implements Runnable {
private int start;
private Semaphore semaphore;
private ThreadSynchronization(int start, Semaphore semaphore) {
this.start = start;
this.semaphore = semaphore;
}
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(1, true);
semaphore.acquireUninterruptibly();
start(1, semaphore);
start(2, semaphore);
semaphore.release();
}
private static void start(int start, Semaphore semaphore) {
ThreadSynchronization ts = new ThreadSynchronization(start, semaphore);
Thread thread = new Thread(ts);
thread.start();
while (thread.getState() != Thread.State.WAITING) ;
}
#Override
public void run() {
for (int i = start; i <= 100; i += 2) {
semaphore.acquireUninterruptibly();
System.out.println("Thread " + start + ": The number is '" + i + "'");
semaphore.release();
}
}
}
One thread can keep aquiring and releasing the Semaphore, while the other thread starves.
You can do this with wait and notify, try this:
import java.util.concurrent.atomic.AtomicInteger;
class Odd implements Runnable {
private AtomicInteger integer;
private final Object lock;
public Odd(AtomicInteger integer, Object lock) {
this.integer = integer;
this.lock = lock;
}
#Override
public void run() {
synchronized (lock) {
try {
while (integer.get() <= 100) {
while (integer.get() % 2 == 0) {
lock.notify();
lock.wait();
}
if (integer.get() <= 100) {
System.out.println("Thread " +
Thread.currentThread().getName() + ": The number is '" + integer.get() + "'");
}
integer.getAndIncrement();
lock.notify();
}
} catch (Exception e) {
}
}
}
}
class Even implements Runnable {
private AtomicInteger integer;
private final Object lock;
public Even(AtomicInteger integer, Object lock) {
this.integer = integer;
this.lock = lock;
}
#Override
public void run() {
synchronized (lock) {
try {
while (integer.get() <= 100) {
while (integer.get() % 2 != 0) {
lock.notify();
lock.wait();
}
if (integer.get() <= 100) {
System.out.println("Thread " +
Thread.currentThread().getName() + ": The number is '" + integer.get() + "'");
}
integer.getAndIncrement();
lock.notify();
}
} catch (Exception e) {
}
}
}
}
public class ThreadSynchronization {
public static void main(String[] args) throws Exception{
Object lock = new Object();
AtomicInteger integer = new AtomicInteger(1);
Odd odd = new Odd(integer, lock);
Even even = new Even(integer, lock);
Thread thread1 = new Thread(odd, "1");
Thread thread2 = new Thread(even, "2");
thread1.start();
thread2.start();
thread1.join();
thread2.join();
}
}
Use an object to arbiter:
public class Switch {
private boolean expected;
public Switch(boolean init) {
expected = init;
}
public void waitFor(boolean value) {
synchronized(this) {
while (value != expected) {
try {
wait();
} catch (InterruptedException ex) {
// deal with it
}
}
expected = !expected;
notifyAll();
}
}
}
Then:
public class ThreadSynchronization implements Runnable {
private static Switch arbiter = new Switch(true);
private int start;
private ThreadSynchronization(int start) {
this.start = start;
}
public static void main(String[] args) {
start(1);
start(2);
}
private static void start(int start) {
ThreadSynchronization ts = new ThreadSynchronization(start);
Thread thread = new Thread(ts);
thread.start();
}
#Override
public void run() {
boolean odd = start%2 != 0;
for (int i = start; i <= 100; i += 2) {
arbiter.waitFor(odd);
System.out.println("Thread " + start + ": The number is '" + i + "'");
}
}
}
You was very close to the right solution, but the task requires 2 semaphores:
public class ThreadSynchronization implements Runnable {
private int start;
private Semaphore semaphore1;
private Semaphore semaphore2;
private ThreadSynchronization(int start, Semaphore semaphore1, Semaphore semaphore2) {
this.start = start;
this.semaphore1 = semaphore1;
this.semaphore2 = semaphore2;
}
private static void start(int start, Semaphore semaphore1, Semaphore semaphore2) {
ThreadSynchronization ts = new ThreadSynchronization(start, semaphore1, semaphore2);
Thread thread = new Thread(ts);
thread.start();
}
#Override
public void run() {
for (int i = start; i <= 100; i += 2) {
semaphore1.acquireUninterruptibly();
System.out.println("Thread " + start + ": The number is '" + i + "'");
semaphore2.release();
}
}
public static void main(String[] args) {
Semaphore semaphore1 = new Semaphore(1);
Semaphore semaphore2 = new Semaphore(0);
start(1, semaphore1, semaphore2);
start(2, semaphore2, semaphore1); // in reverse order
}
}
For this simple task it is enough to use AutomicInteger:
public static class CounterTask implements Runnable {
private final int id;
private final AtomicInteger counter;
private final int max;
private final IntPredicate predicate;
public CounterTask(int id, AtomicInteger counter, int max, IntPredicate predicate) {
this.id = id;
this.counter = counter;
this.max = max;
this.predicate = predicate;
}
#Override
public void run() {
while (counter.get() <= max) {
if (predicate.test(counter.get())) {
System.out.format("Thread %d: The number is '%d'\n", id, counter.get());
counter.incrementAndGet();
}
}
}
}
public static void main(String... args) throws InterruptedException {
final int max = 100;
final AtomicInteger counter = new AtomicInteger();
Thread oddThread = new Thread(new CounterTask(1, counter, max, val -> val % 2 == 0));
Thread evenThread = new Thread(new CounterTask(2, counter, max, val -> val % 2 != 0));
oddThread.start();
evenThread.start();
oddThread.join();
evenThread.join();
}
While wait and notify can do the job, I think the use of Semaphore can make for more readable code. The code below focusses on a solution for threads "talking" to each other and synchornizing where needed: I imagine in a real use case 2 threads do important work and at some point need to synchronize and determine who goes first.
import java.util.concurrent.Semaphore;
public class LockStep {
public static void main(String[] args) {
Semaphore evenTurn = new Semaphore(1);
Semaphore oddTurn = new Semaphore(0);
int max = 50;
Thread even = new Thread(new Worker(evenTurn, oddTurn, max));
even.start();
Thread odd = new Thread(new Worker(oddTurn, evenTurn, max));
odd.start();
try {
even.join();
odd.join();
} catch (Exception e) {
System.out.println("No join for me: " + e);
}
System.out.println("Finished");
}
static class Worker implements Runnable {
final Semaphore myTurn;
final Semaphore theirTurn;
final int maxTurns;
public Worker(Semaphore myTurn, Semaphore theirTurn, int maxTurns) {
this.myTurn = myTurn;
this.theirTurn = theirTurn;
this.maxTurns = maxTurns;
}
#Override
public void run() {
int turn = 0;
while (turn < maxTurns) {
try {
myTurn.acquire();
turn += 1;
System.out.println(Thread.currentThread().getName() + " " + turn);
theirTurn.release();
} catch (Exception e) {
System.out.println("Oops: " + e);
}
}
}
}
}
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);
}
}
}
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);
}
}
}