I was attempting to solve a multi threaded problem and I am facing difficulties getting to know its behavior.
The problem is:
There are 2 threads which simultaneously consume even and odd numbers. I have to introduce the thread communication between them to have the "consumption" in natural ordering.
here is my code
public class EvenOddDemo {
public static void main(String[] args) {
Number n = new Number();
EvenThread et = new EvenThread(n);
OddThread ot = new OddThread(n);
et.start();
ot.start();
}
}
class EvenThread extends Thread {
private Number number;
public EvenThread(Number number) {
this.number = number;
}
#Override
public void run() {
for(int i=0; i<5; i++) {
System.out.println(number.getEven());
}
}
}
class OddThread extends Thread {
private Number number;
public OddThread(Number number) {
this.number = number;
}
#Override
public void run() {
for(int i=0; i<5; i++) {
System.out.println(number.getOdd());
}
}
}
class Number {
private int currentEven = 0;
private int currentOdd = 1;
private volatile String last = "odd";
public synchronized int getEven() {
if("even".equals(last)) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i = currentEven;
last = "even";
currentEven +=2;
notify();
return i;
}
public synchronized int getOdd() {
if("odd".equals(last)) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int i = currentOdd;
last = "odd";
currentOdd +=2;
notify();
return i;
}
}
and the output is
0
2
1
3
4
5
7
6
8
9
But when I debug the code, it prints the numbers in the correct order. Hence I am not able to figure out what I am missing. Please help me. Thanks in advance for your time for this thread.
As far as I can see, there is nothing preventing this from happening, explaining why 2 is displayed before 1 in your output:
OddThread EvenThread
---------- ----------
gets odd
gets even
prints even
prints odd
The lock therefore needs to be around the whole sequence "get/print".
You'll notice that you are never "two numbers apart" in your output, too.
notify chooses any available thread.
The choice is arbitrary and occurs at the discretion of the implementation
If there are more than two threads waiting you could be signalling the "wrong" thread.
Also, note that both of your threads could be just finished in get(Even|Odd) with neither waiting, leading to the notify going nowhere depending upon the scheduling.
You need to be more strict to ensure the ordering. Perhaps two locks, even and odd, would be helpful.
You need to print the number in getEven and getOdd functions and notify the other thread.
But you were notifying and printing the number, so between noti
Modified code:
public class ThreadExp {
public static void main(String[] args) {
Number n = new Number();
EvenThread et = new EvenThread(n);
OddThread ot = new OddThread(n);
et.start();
ot.start();
}
}
class EvenThread extends Thread {
private Number number;
public EvenThread(Number number) {
this.number = number;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
number.getEven();
}
}
}
class OddThread extends Thread {
private Number number;
public OddThread(Number number) {
this.number = number;
}
#Override
public void run() {
for (int i = 0; i < 10; i++) {
number.getOdd();
}
}
}
class Number {
private int currentEven = 0;
private int currentOdd = 1;
private StringBuilder odd;
private StringBuilder even;
private StringBuilder last;
{
odd = new StringBuilder("odd");
even = new StringBuilder("even");
last = odd;
}
public synchronized void getEven() {
if (last == even) {
try {
//System.out.println("inside if in even--->" +Thread.currentThread());
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.out.println("out of if in even--> " + Thread.currentThread());
int i = currentEven;
last = even;
currentEven += 2;
System.out.println(i);
notify();
return;
}
public synchronized void getOdd() {
if (last == odd) {
try {
//System.out.println("inside if in odd--->" +Thread.currentThread());
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//System.out.println("out of if in odd--> " + Thread.currentThread());
int i = currentOdd;
last = odd;
currentOdd += 2;
System.out.println(i);
notify();
return;
}
}
Related
I ran across this barrier code and I cannot understand the barrierPost method.
Im supposed to use this code to solve an exercise where two teams of threads race eachother to count to 10000.
I don't understand why the same condition has different results which are opposite
public class Barrier {
private int currentPosters = 0, totalPosters = 0;
private int passedWaiters = 0, totalWaiters = 1;
/**
* #param totalPosters - Nr of threads required to start the waiting threads
* #param totalWaiters - Nr of threads started later
*/
public Barrier (int totalPosters, int totalWaiters) {
this.totalPosters = totalPosters;
this.totalWaiters = totalWaiters;
}
public synchronized void init(int i) {
totalPosters = i; currentPosters=0;
}
public synchronized void barrierSet(int i) {
totalPosters = i; currentPosters=0;
}
public synchronized void barrierWait() {
boolean interrupted = false;
while (currentPosters = totalPosters) {
try {wait();}
catch (InterruptedException ie) {interrupted=true;}
}
passedWaiters++;
if (passedWaiters == totalWaiters) {
currentPosters = 0; passedWaiters = 0; notifyAll();
}
if (interrupted) Thread.currentThread().interrupt();
}
public synchronized void barrierPost() {
boolean interrupted = false; // In case a poster thread beats barrierWait, keep count of posters.
while (currentPosters == totalPosters) {
try {wait();}
catch (InterruptedException ie) {interrupted=true;}
}
currentPosters++;
if (currentPosters == totalPosters) notifyAll();
if (interrupted) Thread.currentThread().interrupt();
}
}
Can someone help?
I was asked to write a two-threaded Java program in an interview. In this program one thread should print even numbers and the other thread should print odd numbers alternatively.
Sample output:
Thread1: 1
Thread2: 2
Thread1: 3
Thread2: 4
... and so on
I wrote the following program. One class Task which contains two methods to print even and odd numbers respectively. From main method, I created two threads to call these two methods. The interviewer asked me to improve it further, but I could not think of any improvement. Is there any better way to write the same program?
class Task
{
boolean flag;
public Task(boolean flag)
{
this.flag = flag;
}
public void printEven()
{
for( int i = 2; i <= 10; i+=2 )
{
synchronized (this)
{
try
{
while( !flag )
wait();
System.out.println(i);
flag = false;
notify();
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
public void printOdd()
{
for( int i = 1; i < 10; i+=2 )
{
synchronized (this)
{
try
{
while(flag )
wait();
System.out.println(i);
flag = true;
notify();
}
catch(InterruptedException ex)
{
ex.printStackTrace();
}
}
}
}
}
public class App {
public static void main(String [] args)
{
Task t = new Task(false);
Thread t1 = new Thread( new Runnable() {
public void run()
{
t.printOdd();
}
});
Thread t2 = new Thread( new Runnable() {
public void run()
{
t.printEven();
}
});
t1.start();
t2.start();
}
}
I think this should work properly and pretty simple.
package com.simple;
import java.util.concurrent.Semaphore;
/**
* #author Evgeny Zhuravlev
*/
public class ConcurrentPing
{
public static void main(String[] args) throws InterruptedException
{
Semaphore semaphore1 = new Semaphore(0, true);
Semaphore semaphore2 = new Semaphore(0, true);
new Thread(new Task("1", 1, semaphore1, semaphore2)).start();
new Thread(new Task("2", 2, semaphore2, semaphore1)).start();
semaphore1.release();
}
private static class Task implements Runnable
{
private String name;
private long value;
private Semaphore semaphore1;
private Semaphore semaphore2;
public Task(String name, long value, Semaphore semaphore1, Semaphore semaphore2)
{
this.name = name;
this.value = value;
this.semaphore1 = semaphore1;
this.semaphore2 = semaphore2;
}
#Override
public void run()
{
while (true)
{
try
{
semaphore1.acquire();
System.out.println(name + ": " + value);
value += 2;
semaphore2.release();
}
catch (InterruptedException e)
{
throw new RuntimeException(e);
}
}
}
}
}
Well, there are many alternatives. I would probably use a SynchronousQueue instead (I don't like low-level wait/notify and try to use higher-level concurrency primitives instead). Also printOdd and printEven could be merged into single method and no additional flags are necessary:
public class App {
static class OddEven implements Runnable {
private final SynchronousQueue<Integer> queue = new SynchronousQueue<>();
public void start() throws InterruptedException {
Thread oddThread = new Thread(this);
Thread evenThread = new Thread(this);
oddThread.start();
queue.put(1);
evenThread.start();
}
#Override
public void run() {
try {
while (true) {
int i = queue.take();
System.out.println(i + " (" + Thread.currentThread() + ")");
if (i == 10)
break;
queue.put(++i);
if (i == 10)
break;
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) throws InterruptedException {
new OddEven().start();
}
}
Is there any better way to write the same program?
Well, the thing is, the only good way to write the program is to use a single thread. If you want a program to do X, Y, and Z in that order, then write a procedure that does X, then Y, then Z. There is no better way than that.
Here's what I would have written after discussing the appropriateness of threads with the interviewer.
import java.util.concurrent.SynchronousQueue;
import java.util.function.Consumer;
public class EvenOdd {
public static void main(String[] args) {
SynchronousQueue<Object> q1 = new SynchronousQueue<>();
SynchronousQueue<Object> q2 = new SynchronousQueue<>();
Consumer<Integer> consumer = (Integer count) -> System.out.println(count);
new Thread(new Counter(q1, q2, 2, 1, consumer)).start();
new Thread(new Counter(q2, q1, 2, 2, consumer)).start();
try {
q1.put(new Object());
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
private static class Counter implements Runnable {
final SynchronousQueue<Object> qin;
final SynchronousQueue<Object> qout;
final int increment;
final Consumer<Integer> consumer;
int count;
Counter(SynchronousQueue<Object> qin, SynchronousQueue<Object> qout,
int increment, int initial_count,
Consumer<Integer> consumer) {
this.qin = qin;
this.qout = qout;
this.increment = increment;
this.count = initial_count;
this.consumer = consumer;
}
public void run() {
try {
while (true) {
Object token = qin.take();
consumer.accept(count);
qout.put(token);
count += increment;
}
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
}
How about a shorter version like this:
public class OddEven implements Runnable {
private static volatile int n = 1;
public static void main(String [] args) {
new Thread(new OddEven()).start();
new Thread(new OddEven()).start();
}
#Override
public void run() {
synchronized (this.getClass()) {
try {
while (n < 10) {
this.getClass().notify();
this.getClass().wait();
System.out.println(Thread.currentThread().getName() + ": " + (n++));
this.getClass().notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
There is a bit of a trick to kick-start the threads properly - thus the need to an extra notify() to start the whole thing (instead of have both processes wait, or required the main Thread to call a notify) and also to handle the possibility that a thread starts, does it's work and calls notify before the second thread has started :)
My initial answer was non-functional. Edited:
package test;
public final class App {
private static volatile int counter = 1;
private static final Object lock = new Object();
public static void main(String... args) {
for (int t = 0; t < 2; ++t) {
final int oddOrEven = t;
new Thread(new Runnable() {
#Override public void run() {
while (counter < 100) {
synchronized (lock) {
if (counter % 2 == oddOrEven) {
System.out.println(counter++);
}
}
}
}
}).start();
}
}
}
I’m writing a program that implements the Producer Consumer problem in Java using multithreading concepts. Below are few details how I’m supposed to do it:
1) The main thread should create a buffer with capacity specified as a command line argument. The number of producer and consumer threads are also specified as command line arguments. I’m supposed to assign a unique number to each producer and consumer thread. How do I assign a unique number to producer and consumer threads?
2) The producer thread operates in an infinite loop. It produces a data item (a string) with the following format: <producer number>_<data item number>. For example the 1st data item from thread number 1 will be 1_1 and second data item from thread number 3 will be 3_2. How do create data items in such a format?
3) Then the Producer thread writes an entry into the producer log file (< producer number > “Generated” <data item>). Upon writing the log entry, it attempts to insert into the buffer. If insertion is successful, it creates an entry into the log file (<producer number> <data item> “Insertion successful”). How do I write such a code?
Below is the Java code I wrote.
import java.util.*;
import java.util.logging.*;
public class PC2
{
public static void main(String args[])
{
ArrayList<Integer> queue = new ArrayList<Integer>();
int size = Integer.parseInt(args[2]);
Thread[] prod = new Thread[Integer.parseInt(args[0])];
Thread[] cons = new Thread[Integer.parseInt(args[1])];
for(int i=0; i<prod.length; i++)
{
prod[i] = new Thread(new Producer(queue, size));
prod[i].start();
}
for(int i=0; i<cons.length; i++)
{
cons[i] = new Thread(new Consumer(queue, size));
cons[i].start();
}
}
}
class Producer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Producer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true){
for(int i=0; i<size; i++)
{
System.out.println("Produced: "+i+" by id " +Thread.currentThread().getId());
try
{
produce(i);
Thread.sleep(3000);
}
catch(Exception e)
{
Logger.getLogger(Producer.class.getName()).log(Level.SEVERE, null, e);
}
}}
}
public void produce(int i) throws InterruptedException
{
while(queue.size() == size)
{
synchronized(queue)
{
System.out.println("Queue is full "+Thread.currentThread().getName() +" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized(queue)
{
queue.add(i);
queue.notifyAll();
}
}
}
class Consumer extends Thread
{
private final ArrayList<Integer> queue;
private final int size;
public Consumer(ArrayList<Integer> queue, int size)
{
this.queue = queue;
this.size = size;
}
public void run()
{
while(true)
{
try
{ System.out.println("Consumed: "+consume());
Thread.sleep(1000);
}
catch(Exception e)
{
Logger.getLogger(Consumer.class.getName()).log(Level.SEVERE, null, e);
}
}
}
public int consume() throws InterruptedException
{
while(queue.isEmpty())
{
synchronized(queue)
{
System.out.println("Queue is empty "+Thread.currentThread().getName()+" is waiting, size: "+queue.size());
queue.wait();
}
}
synchronized (queue)
{
queue.notifyAll();
System.out.println("Consumed by id "+Thread.currentThread().getId());
return (Integer) queue.remove(0);
}
}
}
How can I carry out the above steps?
I’m supposed to assign a unique number to each producer and consumer
thread. How do I assign a unique number to producer and consumer
threads?
Add an instance (non-static) variable to the Producer/Consumer classes. When you initialize the new Producer/Consumer Objects, pass in the unique number. You can keep track of what number you're on with an int counter in your main class.
2) The producer thread operates in an infinite loop. It produces a
data item (a string) with the following format: < producer number >_<
data item number > . For example the 1st data item from thread number
1 will be 1_1 and second data item from thread number 3 will be 3_2.
How do create data items in such a format?
Use synchronized methods and/or atomic variables. Look into Java Concurrency.
3) Then the Producer thread writes an entry into the producer log file
(< producer number > “Generated” < data item >). Upon writing the log
entry, it attempts to insert into the buffer. If insertion is
successful, it creates an entry into the log file (< producer number >
< data item > “Insertion successful”). How do I write such a code?
My answer is the same as the previous question: read about Java concurrency. Spend an hour reading about synchronization, locks, and atomic variables and I guarantee you will easily write your program.
For producer consumer problem best solution is BlockingQueue. I was testing a few things so designed same kind of program now modified it as per your need.
See if it helps.
import java.util.concurrent.*;
public class ThreadingExample {
public static void main(String args[]){
BlockingQueue<Message> blockingQueue = new ArrayBlockingQueue<Message>(100);
ExecutorService exec = Executors.newCachedThreadPool();
exec.execute(new Producer(blockingQueue));
exec.execute(new Consumer(blockingQueue));
}
}
class Message{
private static int count=0;
int messageId;
Message(){
this.messageId=count++;
System.out.print("message Id"+messageId+" Created ");
}
}
class Producer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Producer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
#Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Producer Started");
try {
blockingQueue.put(new Message());
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Producer Done");
}
}
}
class Consumer implements Runnable{
private BlockingQueue<Message> blockingQueue;
Consumer(BlockingQueue<Message> blockingQueue){
this.blockingQueue=blockingQueue;
}
#Override
public void run(){
while(!Thread.interrupted()){
System.out.print("Concumer Started");
try{
Message message = blockingQueue.take();
System.out.print("message Id"+message.messageId+" Consumed ");
}
catch(InterruptedException e){
e.printStackTrace();
}
System.out.println("Concumer Done");
}
}
}
I tried the following which might work for you, except for the buffer condition on 3, which you can add the part of the code by yourself.
Hope this helps.
public class Message {
private String msg;
public Message(String msg) {
super();
this.msg = msg;
}
public String getMsg(){
return msg;
}
}
import java.util.concurrent.BlockingQueue;
public class Producer implements Runnable {
private BlockingQueue<Message> queue;
private boolean run = true;
public Producer(BlockingQueue<Message> queue) {
super();
this.queue = queue;
}
public void setRun(boolean val) {
this.run = val;
}
#Override
public void run() {
int i = 0;
while (run) {
Message msg = new Message(Thread.currentThread().getName() + "_"+ i);
try {
Thread.sleep(i * 100);
queue.put(msg);
System.out.println("Producer: "+Thread.currentThread().getName()+" produced and added to the queue: "+msg.getMsg());
} catch (InterruptedException e) {
e.printStackTrace();
}
i++;
if(i==10){
setRun(false);
System.out.println(Thread.currentThread().getName()+" stopped");
}
}
}
}
import java.util.concurrent.BlockingQueue;
public class Consumer implements Runnable{
private BlockingQueue<Message> queue;
private boolean run = true;
public Consumer(BlockingQueue<Message> queue) {
super();
this.queue = queue;
}
public void setRun(boolean val){
this.run = val;
}
#Override
public void run() {
while(run){
try {
Thread.sleep(100);
Message msg = queue.take();
System.out.println("Consumer: "+Thread.currentThread().getName()+" generated/consumed "+msg.getMsg());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumerMain {
public static void main(String[] args) {
System.out
.println("please enter the number of producer:consumer:size of the queue in order");
Scanner scan = new Scanner(System.in);
Thread[] prodThreads = new Thread[scan.nextInt()];
Thread[] consThreads = new Thread[scan.nextInt()];
BlockingQueue<Message> queue = new ArrayBlockingQueue<Message>(scan.nextInt());
for (int i = 0; i < prodThreads.length; i++) {
prodThreads[i] = new Thread(new Producer(queue), "" + i);
prodThreads[i].start();
}
for (int i = 0; i < consThreads.length; i++) {
consThreads[i] = new Thread(new Consumer(queue), "" + i);
consThreads[i].start();
}
}
}
Please refer the below code. You can change the constant values based on the command line arguments. I have tested the code, its working as per your requirement.
import java.util.LinkedList;
import java.util.Queue;
public class ProducerConsumerProblem {
public static int CAPACITY = 10; // At a time maximum of 10 tasks can be
// produced.
public static int PRODUCERS = 2;
public static int CONSUMERS = 4;
public static void main(String args[]) {
Queue<String> mTasks = new LinkedList<String>();
for (int i = 1; i <= PRODUCERS; i++) {
Thread producer = new Thread(new Producer(mTasks));
producer.setName("Producer " + i);
producer.start();
}
for (int i = 1; i <= CONSUMERS; i++) {
Thread consumer = new Thread(new Consumer(mTasks));
consumer.setName("Consumer " + i);
consumer.start();
}
}
}
class Producer implements Runnable {
Queue<String> mSharedTasks;
int taskCount = 1;
public Producer(Queue<String> mSharedTasks) {
super();
this.mSharedTasks = mSharedTasks;
}
#Override
public void run() {
while (true) {
synchronized (mSharedTasks) {
try {
if (mSharedTasks.size() == ProducerConsumerProblem.CAPACITY) {
System.out.println("Producer Waiting!!");
mSharedTasks.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while (mSharedTasks.size() != ProducerConsumerProblem.CAPACITY) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
}
String produceHere = Thread.currentThread().getName()
+ "_Item number_" + taskCount++;
synchronized (mSharedTasks) {
mSharedTasks.add(produceHere);
System.out.println(produceHere);
if (mSharedTasks.size() == 1) {
mSharedTasks.notifyAll(); // Informs consumer that there
// is something to consume.
}
}
}
}
}
}
class Consumer implements Runnable {
Queue<String> mSharedTasks;
public Consumer(Queue<String> mSharedTasks) {
super();
this.mSharedTasks = mSharedTasks;
}
#Override
public void run() {
while (true) {
synchronized (mSharedTasks) {
if (mSharedTasks.isEmpty()) { // Checks whether there is no task
// to consume.
try {
mSharedTasks.wait(); // Waits for producer to produce!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
while (!mSharedTasks.isEmpty()) { // Consumes till task list is
// empty
try {
// Consumer consumes late hence producer has to wait...!
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (mSharedTasks) {
System.out.println(Thread.currentThread().getName()
+ " consumed " + mSharedTasks.poll());
if (mSharedTasks.size() == ProducerConsumerProblem.CAPACITY - 1)
mSharedTasks.notifyAll();
}
}
}
}
}
public class ProducerConsumerTest {
public static void main(String[] args) {
CubbyHole c = new CubbyHole();
Producer p1 = new Producer(c, 1);
Consumer c1 = new Consumer(c, 1);
p1.start();
c1.start();
}
}
class CubbyHole {
private int contents;
private boolean available = false;
public synchronized int get() {
while (available == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
available = false;
notifyAll();
return contents;
}
public synchronized void put(int value) {
while (available == true) {
try {
wait();
} catch (InterruptedException e) {
}
}
contents = value;
available = true;
notifyAll();
}
}
class Consumer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Consumer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
int value = 0;
for (int i = 0; i < 10; i++) {
value = cubbyhole.get();
System.out.println("Consumer #"
+ this.number
+ " got: " + value);
}
}
}
class Producer extends Thread {
private CubbyHole cubbyhole;
private int number;
public Producer(CubbyHole c, int number) {
cubbyhole = c;
this.number = number;
}
public void run() {
for (int i = 0; i < 10; i++) {
cubbyhole.put(i);
System.out.println("Producer #" + this.number
+ " put: " + i);
try {
sleep((int) (Math.random() * 100));
} catch (InterruptedException e) {
}
}
}
}
I am trying to create an implementation where multiple threads print alternate values of sequence. So here thread1 will print 1,4,7 thread2 will print 2,5,8 thread3 will print 3,6,9. I am using Atomic integer and modulo function.
Below implementation works fine in the sense that first thread prints 1,4,7 while second prints 2,5,8 and third prints 3,6,9 but problem is that sequence is not maintained i.e output can be like 1,3,2,4,5,7,8,6,9 while i want sequence to be maintained as proper threads shld print those values.
One condition is i don't want to use synchronize. [Just for learning purpose]
import java.util.concurrent.atomic.AtomicInteger;
public class ThreeThreadsOrderedLockLess {
AtomicInteger sharedOutput = new AtomicInteger(0);
public static void main(String args[]) {
ThreeThreadsOrderedLockLess t = new ThreeThreadsOrderedLockLess();
ThreadTasks t1 = t.new ThreadTasks(0);
ThreadTasks t2 = t.new ThreadTasks(1);
ThreadTasks t3 = t.new ThreadTasks(2);
Thread ts1 = new Thread(t1);
Thread ts2 = new Thread(t2);
Thread ts3 = new Thread(t3);
ts1.start();
ts2.start();
ts3.start();
}
private class ThreadTasks implements Runnable {
private final int threadPosition;
public ThreadTasks(int threadPosition) {
super();
this.threadPosition = threadPosition;
}
#Override
public void run() {
while (sharedOutput.get() < 9) {
if (sharedOutput.get() % 3 == this.threadPosition) {
System.out.println("Printing output for Thread: "
+ this.threadPosition + " "
+ sharedOutput.incrementAndGet());
}
}
}
}
}
You should print first, and increment after:
int value = sharedOutput.get() + 1;
System.out.println("Printing output for Thread: "
+ this.threadPosition + " "
+ value);
sharedOutput.incrementAndGet();
That said, all the threads are busy looping, which will lead to 100% CPU usage. You should synchronize the threads instead.
Below code snippet will print numbers in sequence and all threads will be terminated gracefully after the task.
Used AtomicInteger, which is thread-safe for printing the numbers and same logic can be applied to print as till any number with any number of threads.
import java.util.concurrent.atomic.AtomicInteger;
public class PrintNumSequence
{
public static void main(String[] args)
{
AtomicInteger atomicInteger = new AtomicInteger(0);
new NumPrinter(atomicInteger, 0).start();// thread0
new NumPrinter(atomicInteger, 1).start();// thread1
new NumPrinter(atomicInteger, 2).start();// thread2
}
}
class NumPrinter extends Thread
{
private AtomicInteger atomicInteger;
private int threadNum;
public NumPrinter(AtomicInteger atomicInteger, int threadNum)
{
this.atomicInteger = atomicInteger;
this.threadNum = threadNum;
}
#Override
public void run()
{
int num = atomicInteger.intValue();
do
{
synchronized (atomicInteger)
{
num = atomicInteger.intValue();
// If number is 9 then stop.
if (num > 9)
{
atomicInteger.notifyAll();
break;
}
// 3 is number of threads
if ((num % 3) == threadNum)
{
System.out.println("Thread-" + threadNum + " -->" + num);
num = atomicInteger.incrementAndGet();
}
atomicInteger.notifyAll();
try
{
atomicInteger.wait();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
} while (true);
}
}
This is because the time slice for each thread is determined by the OS. So it is possible that thread x increments the shared number but before printing the time slice is passed to the next thread y which now reads the shared number and prints it after incrementing (assuming that thread y got more time than thread x to increament and print the shared number)
.
use wait(), notify(), notifyall() methods of the Java.
you can also take a look at this Tutorial of these methods.
Hope this would be helpful to solve your issue. . .
the output of this example is as under.
Put: 1
Got: 1
Put: 2
Got: 2
Put: 3
Got: 3
Put: 4
Got: 4
Put: 5
Got: 5
This should work:
package com.sid;
import java.util.concurrent.atomic.AtomicInteger;
public class NumberSequence {
private AtomicInteger sharedOutput = new AtomicInteger(0);
private Object object = new Object();
public static void main(String args[]) {
NumberSequence t = new NumberSequence();
ThreadTasks t1 = t.new ThreadTasks(0);
ThreadTasks t2 = t.new ThreadTasks(1);
ThreadTasks t3 = t.new ThreadTasks(2);
Thread ts1 = new Thread(t1);
Thread ts2 = new Thread(t2);
Thread ts3 = new Thread(t3);
ts1.start();
ts2.start();
ts3.start();
}
private class ThreadTasks implements Runnable {
private final int threadPosition;
public ThreadTasks(int threadPosition) {
super();
this.threadPosition = threadPosition;
}
#Override
public void run() {
while (sharedOutput.get() < 10) {
synchronized (object) {
if (sharedOutput.get() % 3 == this.threadPosition) {
if(sharedOutput.get() < 10)
System.out.println("Printing output for Thread: "
+ this.threadPosition + " "
+ sharedOutput.incrementAndGet());
}
}
}
}
}
}
Proper synchronization would help you get the clear answer. I've improved the implementation, you should solve your questions.
int threadId;
int moduluos;
int numOfThreads;
public ThreadTasks(int id, int nubOfThreads) {
threadId = id;
this.numOfThreads = nubOfThreads;
moduluos = threadId%numOfThreads;
}
public void run() {
print();
}
private void print() {
try {
while (true) {
synchronized (monitor) {
if (number.get() % numOfThreads != moduluos) {
monitor.wait();
} else {
System.out.println("ThreadId [" + threadId
+ "] printing -->"
+ number.getAndIncrement());
monitor.notifyAll();
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package test.mk.thread;
import java.util.concurrent.atomic.AtomicInteger;
public class MkThread2 {
int nextThreadToRun = 1;
int[] arr = {1,2,3,4,5,6,7,8,9,10,11};
AtomicInteger nextArrayIndex = new AtomicInteger(0);
boolean token = true;
public static void main(String[] args) {
MkThread2 mkThread = new MkThread2();
Thread t1 = new Thread(new Worker2(1, mkThread));
Thread t2 = new Thread(new Worker2(2, mkThread));
Thread t3 = new Thread(new Worker2(3, mkThread));
t1.start();
t2.start();
t3.start();
}
}
class Worker2 implements Runnable{
volatile int threadNo;
private MkThread2 mkThread;
private String threadName;
Worker2(int threadNo, MkThread2 mkThread){
this.threadNo = threadNo;
this.mkThread = mkThread;
this.threadName = "Thread:"+threadNo ;
}
public void run(){
try{
synchronized (mkThread) {
while(mkThread.token){
while(threadNo != mkThread.nextThreadToRun){
mkThread.wait();
}
if(mkThread.token){//double checking
System.out.print(threadName+ "->" + mkThread.arr[mkThread.nextArrayIndex.get()]);
if(threadNo == 3) System.out.println();
mkThread.nextThreadToRun = getNextThread(threadNo);
if(mkThread.nextArrayIndex.get() == mkThread.arr.length-1){
mkThread.token = false;
}
mkThread.nextArrayIndex.incrementAndGet();
}
mkThread.notifyAll();
}
}
}
catch(Exception e){
e.printStackTrace();
}
}
private int getNextThread(int threadNo){
int result = -1;
switch (threadNo) {
case (1):
result = 2;
break;
case (2):
result = 3;
break;
case (3):
result = 1;
break;
}
return result;
}
}
import java.util.concurrent.atomic.AtomicInteger;
public class Print123456789 {
public static void main(String[] args) {
print p1 = new print(0);
print p2 = new print(1);
print p3 = new print(2);
Thread t1 = new Thread(p1);
Thread t2 = new Thread(p2);
Thread t3 = new Thread(p3);
t1.start();
t2.start();t3.start();
}
}
class print implements Runnable {
private int threadNumber;
private static AtomicInteger atomicInteger = new AtomicInteger(0);
public print(int threadNumber) {
super();
this.threadNumber = threadNumber;
}
public void run(){
try{
while(atomicInteger.get() < 10){
synchronized (atomicInteger) {
if((atomicInteger.get()%3) == this.threadNumber){
System.out.println(atomicInteger.getAndIncrement() + " Thread :" + this.threadNumber );
atomicInteger.notifyAll();
}
else
atomicInteger.wait();
}
}
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
This can be better implemented using blocking queues. Define a worker holding a blocking queue. The workers waits on the queue until it receives a number in it. It prints the number it receives, increments it and passes it on to the next worker in the chain. Refer here for the full solution.
package threeThread;
class Task implements Runnable {
String message;
ThreeThread lock;
int i = 0;
int p;
public Task(String text, ThreeThread obj, int p) {
message = text;
this.lock = obj;
this.p = p;
}
#Override
public void run() {
while(true) {
synchronized (lock) {
while(!((lock.status % 3) == 0) && p == 1){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while(!((lock.status % 3) == 1) && p == 2){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
while(!((lock.status % 3) == 2) && p == 3){
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("thread: " + p + " : " + message);
lock.status++;
lock.notifyAll();
}
}
}
}
public class ThreeThread {
volatile int status = 0;
public static void main(String[] args) {
ThreeThread lock = new ThreeThread();
Thread t1 = new Thread(new Task("Hello", lock,1));
Thread t2 = new Thread(new Task("Good", lock,2));
Thread t3 = new Thread(new Task("Morning", lock,3));
t1.start();
t2.start();
t3.start();
}
}
I am putting code to print 1-100 using 5 threads. One can use any number of thread to print output in round robin fashion.
Basic concept is to lock one object and notify other for executing the printing of value.
public class PrintOneToHundredUsing5Threads {
public static void main(String[] args) {
List<Object> objList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
objList.add(new Object());
}
for (int i = 0; i < 5; i++) {
Thread t = new Thread(new PrintThread(objList.get(i), objList.get((i + 1) % 5)));
t.setName("Thread" + i);
t.start();
}
}
}
class PrintThread implements Runnable {
Object current;
Object next;
volatile static int i = 1;
PrintThread(Object cur, Object next) {
this.current = cur;
this.next = next;
}
#Override
public void run() {
for (; i <= 100;) {
synchronized (current) {
synchronized (next) {
next.notify();
System.out.println(Thread.currentThread().getName() + " Value : " + i++);
}
try {
current.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
You can use below code to print sequential numbers using multiple threads -
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ThreadCall extends Thread {
private BlockingQueue<Integer> bq = new ArrayBlockingQueue<Integer>(10);
private ThreadCall next;
public void setNext(ThreadCall t) {
this.next = t;
}
public void addElBQ(int a) {
this.bq.add(a);
}
public ThreadCall(String name) {
this.setName(name);
}
#Override
public void run() {
int x = 0;
while(true) {
try {
x = 0;
x = bq.take();
if (x!=0) {
System.out.println(Thread.currentThread().getName() + " =>" + x);
if (x >= 100) System.exit(0); // Need to stop all running threads
next.addElBQ(x+1);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
int THREAD_COUNT = 10;
List<ThreadCall> listThread = new ArrayList<>();
for (int i=1; i<=THREAD_COUNT; i++) {
listThread.add(new ThreadCall("Thread " + i));
}
for (int i = 0; i < listThread.size(); i++) {
if (i == listThread.size()-1) {
listThread.get(i).setNext(listThread.get(0));
}
else listThread.get(i).setNext(listThread.get(i+1));
}
listThread.get(0).addElBQ(1);
for (int i = 0; i < listThread.size(); i++) {
listThread.get(i).start();
}
}
}
Hope this will resolve your problem.
public class PrintThreadsInSerial {
public static void main(String[] args) {
Thread t = new Thread(new Job());
t.start();
}
}
class Job implements Runnable {
#Override
public void run() {
while (true) {
for (int i = 1; i <= 3; i++) {
System.out.println(i);
}
}
}
}
The ThreadSynchronization class can be used to print numbers between 'n' no. of threads in sequence.
The logic is to create a common object between each of the consecutive threads and use 'wait', 'notify' to print the numbers in sequence.
Note: Last thread will share an object with the first thread.
You can change the 'maxThreads' value to increase or decrease the number of thread in the program before running it.
import java.util.ArrayList;
import java.util.List;
public class ThreadSynchronization {
public static int i = 1;
public static final int maxThreads = 10;
public static void main(String[] args) {
List<Object> list = new ArrayList<>();
for (int i = 0; i < maxThreads; i++) {
list.add(new Object());
}
Object currObject = list.get(maxThreads - 1);
for (int i = 0; i < maxThreads; i++) {
Object nextObject = list.get(i);
RunnableClass1 a = new RunnableClass1(currObject, nextObject, i == 0 ? true : false);
Thread th = new Thread(a);
th.setName("Thread - " + (i + 1));
th.start();
currObject = list.get(i);
}
}
}
class RunnableClass implements Runnable {
private Object currObject;
private Object nextObject;
private boolean firstThread;
public RunnableClass(Object currObject, Object nextObject, boolean first) {
this.currObject = currObject;
this.nextObject = nextObject;
this.firstThread = first;
}
#Override
public void run() {
int i = 0;
try {
if (firstThread) {
Thread.sleep(5000);
firstThread = false;
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
synchronized (nextObject) {
nextObject.notify();
}
}
while (i++ < Integer.MAX_VALUE) {
synchronized (currObject) {
currObject.wait();
}
System.out.println(Thread.currentThread().getName() + " - " + ThreadSynchronization.i++);
Thread.sleep(1000);
synchronized (nextObject) {
nextObject.notify();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public class PrintSeqNumUsingAltThreads {
public static void main(String[] args) {
AtomicInteger counter = new AtomicInteger(0);
int numThreads = 3;
Thread t1 = new Thread(new SeqNumPrinter(counter, 0, numThreads));
Thread t2 = new Thread(new SeqNumPrinter(counter, 1, numThreads));
Thread t3 = new Thread(new SeqNumPrinter(counter, 2, numThreads));
t1.currentThread().setName("T1");
t2.currentThread().setName("T2");
t3.currentThread().setName("T3");
t1.start();
t2.start();
t3.start();
}
}
public class SeqNumPrinter implements Runnable {
AtomicInteger atmCounter;
Integer threadPosition;
Integer numThreads;
public SeqNumPrinter(AtomicInteger counter, int position, int numThreads) {
this.atmCounter = counter;
this.threadPosition = position;
this.numThreads = numThreads;
}
#Override
public void run() {
while (atmCounter.get() < 10) {
if (atmCounter.get() % numThreads == threadPosition) {
System.out.println("Printing value : " + atmCounter.getAndIncrement() + ", by thread : " +
Thread.currentThread().getName());
}
}
}
}
Output :
Printing value : 0, by thread : Thread-0 Printing value : 1, by
thread : Thread-1 Printing value : 3, by thread : Thread-0
Printing value : 2, by thread : Thread-2 Printing value : 4, by
thread : Thread-1 Printing value : 6, by thread : Thread-0
Printing value : 5, by thread : Thread-2 Printing value : 7, by
thread : Thread-1 Printing value : 9, by thread : Thread-0
Printing value : 8, by thread : Thread-2
I have two very similar programs each trying to run two threads OddThread and EvenThread and trying to print the odd and even numbers in sequence . While the first one works , the second one hangs . Can anyone please pinpoint the bug in the second program ?
The first one which works :
public class ThreadTest {
public static void main(String[] args) {
System.out.println("Odd Even test");
NumHolder objNumHolder = new NumHolder();
Odd o1 = new Odd(objNumHolder, "Odd Number Thread");
Even e1 = new Even(objNumHolder, "Even Number Thread");
o1.start();
e1.start();
}
}
class NumHolder {
private int intCurrNum;
private boolean isEven = false;
public synchronized void printOddNumber(String tname) {
while (isEven == true){
try {
wait();
}catch (InterruptedException e) {
}
}
isEven = true;
System.out.println("Thread Name="+tname + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
public synchronized void printEvenNumber(String tname) {
while (isEven == false) {
try {
wait();
} catch (InterruptedException e) {
}
}
isEven = false;
System.out.println("Thread Name="+tname + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
class Even extends Thread {
private NumHolder objNumHolder;
public Even(NumHolder p_objNumHolder, String name) {
super(name);
objNumHolder=p_objNumHolder;
}
public void run() {
for (int i = 0; i < 10; i++) {
objNumHolder.printEvenNumber(getName());
}
}
}
class Odd extends Thread {
private NumHolder objNumHolder;
public Odd(NumHolder p_objNumHolder,String name) {
super(name);
objNumHolder = p_objNumHolder;
}
public void run() {
for (int i = 0; i < 10; i++) {
objNumHolder.printOddNumber(getName());
}
}
}
The second code which hangs :
class PrintClass {
int intCurrNum;
private boolean isEven = false;
synchronized void printOdd(){
while(isEven){
try{
wait();
}catch(InterruptedException ie){
System.out.println("Interrupted exception in printOdd()");
ie.printStackTrace();
}
isEven = true;
System.out.println("Thread Name="+Thread.currentThread().getName() + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
synchronized void printEven(){
while(!isEven){
try{
wait();
}catch(InterruptedException ie){
System.out.println("Interrupted exception in printEven()");
ie.printStackTrace();
}
isEven = false;
System.out.println("Thread Name="+Thread.currentThread().getName() + "===Number="+intCurrNum);
intCurrNum += 1;
notifyAll();
}
}
}
class ThreadOdd extends Thread {
PrintClass pc = null;
ThreadOdd(PrintClass pc , String name){
super(name);
this.pc = pc;
}
public void run(){
for (int i = 0; i < 10; i++) {
pc.printOdd();
}
}
}
class ThreadEven extends Thread {
PrintClass pc = null;
ThreadEven(PrintClass pc,String name){
super(name);
this.pc = pc;
}
public void run(){
for (int i = 0; i < 10; i++) {
pc.printEven();
}
}
}
public class EvenOddPrintClass {
public static void main(String[] args){
PrintClass pc = new PrintClass();
Thread to = new ThreadOdd(pc,"ThreadOdd");
Thread te = new ThreadEven(pc,"ThreadEven");
to.start();
te.start();
}
}
Thanks.
I suggest you run your code in the debugger and step through both threads. It's very educational. You will see exactly where the error is.
In both versions, isEven starts out as false.
In the first version, printOddNumber will skip the whole while loop, print the odd number, set isEven to true and notify the even thread, which will print the even number and notify the odd thread again etc. in sequence.
In the second version, printOddNumber will skip the whole while loop, including printing the number and notifying the even thread. After 10 attempts it will exit without having printed anything, and leaving the even thread hanging without ever having notified it.
Interesting. So initially the isEven = false. If the printOdd() is called first then the while (isEven) test is false so printOdd() will exit immediately without generating any output. The while loops in your first program only encompass the wait test, not the entire method.
Then when printEven() is called by the other thread, it will call wait() and hang since there is no other thread to call notifyAll().
You only should want the while loop around the wait since you are going to exit after you print out the even or odd number anyway, right? So the logic in the first program is correct.
public class CountDownApp
{
public static void main(String[] args)
{
Thread count1 = new CountDownEven();
Thread count2 = new CountDownOdd();
count1.start();
count2.start();
}
}
class CountDownEven extends Thread
{
public void run()
{
for(int i=10;i>0;i-=2)
{
System.out.print(+i+"-");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class CountDownOdd extends Thread
{
public void run()
{
for(int i=9;i>0;i-=2)
{
System.out.print(+i+"-");
try {
Thread.sleep(2);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}