I'm trying to make a parking lot program. I've got multiple threads that put car objects into a queue, then into a shared buffer. Once the sharedBuffer reaches the maximum of 50 elements.
Here is the problem: Once the shared Buffer reaches the maximum amount of elements. I want the thread to start queuing up elements to the queue. Instead the thread waits for the semaphore to open a spot.
public class Buffer {
private LinkedList queue = new LinkedList();
private Semaphore spots = new Semaphore(50);
public synchronized void put(String car) {
try {
spots.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
queue.addLast(car);
notifyAll();
}
public synchronized String get() throws InterruptedException {
String t = (String) queue.removeFirst();
spots.release();
notifyAll();
return t;
}
public int getSize() {
return queue.size();
}
}
Method in my Queue class that either adds the car to the buffer or adds it straight to the queue if the buffer is full.
public void addToQueue(int queue) {
if (queue == 1 && northQueue<20) {
if(buffer.getSize()==50){
northQueue++;
}else{
buffer.put("Volvo");
}
}
}
public void run() {
while (true) {
// System.out.println("Thread: " + threadNumber);
eq.addToQueue(threadNumber);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
}
I am trying to learn how to write a program which performs a given set of tasks in sequence with the help of threads. For example, Writing a program which have 3 different threads print 1111…, 22222…., 333333……, so that the output will be 1,2,3,1,2,3,1,2,3…..? OR for e.g. 2 threads one is printing odd numbers and other even numbers, but the output should be printed in sequence - i.e. one even and then odd.
I would like to learn how to write similar kind of programs in which different threads print different stuff concurrently and the output should be printed in sequence.
What is the basic concept in writing these programs. Can we use ThreadPools/Executors for the purpose ? For e.g. can we use
ExecutorService exectorService = Executors.newFixedThreadPool(3);
Can we use Future, FurtureTask, Callable, execute, submit ...? I know these concepts but I am not able to connect the dots for solving the above scenarios.
Please guide me how to go about writing these kind of programs using multithreading / concurrency.
I have written a program using wait()/notifyAll(). Following is the program. I am not executing the consumer as I am printing the whole sequence at the end. Also I am limiting the capacity of the queue to be 15. So I am basically printing the odd / even range till 15.
public class ProduceEven implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceEven (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
// TODO Auto-generated method stub
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==0) {
taskQueue.add(i);
}
taskQueue.notifyAll();
}
}
}
public class ProduceOdd implements Runnable {
private final List<Integer> taskQueue;
private final int MAX_CAPACITY;
public ProduceOdd (List<Integer> sharedQueue, int size) {
this.taskQueue = sharedQueue;
this.MAX_CAPACITY = size;
}
#Override
public void run() {
int counter = 0;
while (counter < 15) {
try {
produce(counter++);
} catch (InterruptedException e) {
e.getMessage();
}
}
}
private void produce (int i) throws InterruptedException {
synchronized (taskQueue) {
while (taskQueue.size() == MAX_CAPACITY) {
System.out.println("Queue is full : "+Thread.currentThread().getName()+" is waiting , size: "+ taskQueue.size());
taskQueue.wait();
}
Thread.sleep(1000);
if(i%2==1) {
taskQueue.add(i);
}
taskQueue.notify();
}
}
}
public class OddEvenExampleWithWaitAndNotify {
public static void main(String[] args) {
List<Integer> taskQueue = new ArrayList<Integer>();
int MAX_CAPACITY = 15;
Thread tProducerEven = new Thread(new ProduceEven(taskQueue, MAX_CAPACITY), "Producer Even");
Thread tProducerOdd = new Thread(new ProduceOdd(taskQueue, MAX_CAPACITY), "Producer Odd");
tProducerEven.start();
tProducerOdd.start();
try {
tProducerEven.join();
tProducerOdd.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
ListIterator listIterator = taskQueue.listIterator();
System.out.println("Elements Are:: ");
while(listIterator.hasNext()) {
System.out.print(listIterator.next()+" ");
}
}
}
The output which I get is: Elements Are:: 02134657911810131214
The output is all jumbled up. Why is it not in sequence. 01234567891011121314 What am I missing. I would be now trying to make the program using Semaphores. Also how do we make this program using explicit locks?
Yes, you can use ExecutorService as a starting point to run your threads. You can also create and start your Threads manually, that would make no difference.
The important thing is that your Threads will run in parallel if you do not synchronize them (i.e., they have to wait for one another). To synchronize you can, e.g. use Semaphores or other thread communication mechanisms.
You wrote in the comments you have written a producer/consumer program. It's a bit of the same thing. Each time the 1-Thread produces a 1, the 2-Thread must know that it can now produce a 2. When it is finished, it must let the 3-Thread know that it must produce a 3. The basic concepts are the same. Just the threads have both producer and consumer roles.
Hi this is one sample program to print Odd and Even using two thread and using thread synchronization among them.
Also we have used Executor framework which is not mandatory, you can create thread using new Thread() as well. For quick prototype I have used system.exit() which can be replaced with graceful shutdown of threads like, interruption and all.
package com.ones.twos.threes;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class OnesTwos {
public static void main(String[] args) {
BlockingQueue<Integer> bq1 = new ArrayBlockingQueue<Integer>(100);
BlockingQueue<Integer> bq2 = new ArrayBlockingQueue<Integer>(100);
ExecutorService executorService = Executors.newFixedThreadPool(2);
try {
bq1.put(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
executorService.submit(new OddEven(bq1, bq2));
executorService.submit(new OddEven(bq2, bq1));
executorService.shutdown();
}
public static class OddEven implements Runnable {
BlockingQueue<Integer> bq1;
BlockingQueue<Integer> bq2;
public OddEven(BlockingQueue<Integer> bq1, BlockingQueue<Integer> bq2) {
this.bq1 = bq1;
this.bq2 = bq2;
}
#Override
public void run() {
while (true) {
try {
int take = bq1.take();
System.out.println(take);
bq2.offer(take + 1);
if (take > 20)
System.exit(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
Mycode is also similar to Anirban's, except I am not using executor framework,
public class TestThread {
public static void main(String[] args) {
Boolean bol = new Boolean(true);
(new Thread(new Odd(bol), "odd")).start();
(new Thread(new Even(bol), "even")).start();
}
}
public class Even implements Runnable {
private Boolean flag;
public Even(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 2; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
public class Odd implements Runnable {
private Boolean flag;
public Odd(Boolean b) {
this.flag = b;
}
#Override
public void run() {
for (int i = 1; i < 20; i = i + 2) {
synchronized (flag) {
try {
System.out.println(Thread.currentThread().getName()+":"+i);
Thread.sleep(1000);
flag.notify();
flag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
By establishing the thread pool of 3 (ExecutorService exectorService = Executors.newFixedThreadPool(3); you are essentilly limiting the executor capacity to 3 and other incoming threads will be on hold. If you want to run them in paralel you can just submit them at once. If you want to wait for each other and want to find out the result I suggest you use Callable. Personally I really like Callable because after submiting it you can just call the get method of Future, wait for a returned value from the executed thread and then continue to the next one. From the API you can see this:
/**
* Submits a value-returning task for execution and returns a
* Future representing the pending results of the task. The
* Future's {#code get} method will return the task's result upon
* successful completion.
*
*
* If you would like to immediately block waiting
* for a task, you can use constructions of the form
* {#code result = exec.submit(aCallable).get();}
And a very good example here. If you go for the Callable alternative then you don't need a Thread pool. Just a normal executor is fine. Remember to shut the executor down in the end.
class MyNumber {
int i = 1;
}
class Task implements Runnable {
MyNumber myNumber;
int id;
Task(int id, MyNumber myNumber) {
this.id = id;
this.myNumber = myNumber;
}
#Override
public void run() {
while (true) {
synchronized (myNumber) {
while (myNumber.i != id) {
try {
myNumber.wait(); //Wait until Thread with correct next number
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(id);
if (myNumber.i == 1) {
myNumber.i = 2;
} else if (myNumber.i == 2) {
myNumber.i = 3;
} else {
myNumber.i = 1;
}
myNumber.notifyAll();
}
}
}
}
In main method:
MyNumber myNumber = new MyNumber();
new Thread(new Task(1, myNumber)).start();
new Thread(new Task(2, myNumber)).start();
new Thread(new Task(3, myNumber)).start();
Hi here we have used 2 thread one to print even and another to print odd.
Both are separate and have no relation to each other.
But we have to do a synchronization mechanism between them. Also we need a mechanism to let the ball rolling, i.e. start one thread printing.
Each thread is waiting on condition and after doing it's task it lets other thread work and put ownself in waiting state.
Well happy path works fine, but we need special care when even thread is not in waiting state and the signal() from main fires, in that case even thread will never able to wake up and the program hangs.
So to make sure main thread successfully sends a signal() to even thread and even thread does not miss that we have used Phaser(with party) and checking even thread state in while loop in main.
Code is as below.
package com.ones.twos.threes;
import java.util.concurrent.Phaser;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class OnesTwosTrial2 {
public static void main(String[] args) {
Lock lk = new ReentrantLock();
Phaser ph = new Phaser(3); // to let main start the even thread
Condition even = lk.newCondition();
Condition odd = lk.newCondition();
OnesTwosTrial2 onestwostrial2 = new OnesTwosTrial2();
Thread ev = onestwostrial2.new Evens(lk, even, odd, ph);
Thread od = onestwostrial2.new Odds(lk, even, odd, ph);
ev.start();
od.start();
System.out.println("in main before arrive");
ph.arriveAndAwaitAdvance();
System.out.println("in main after arrive");
// we have to make sure odd and even thread is
// started and waiting on respective condition.
// So we used Phaser with 3, because we are having here
// 3 parties (threads)
// main, odd,even. We will signal only when all the
// threads have started.
// and waiting on conditions.
while (!Thread.State.WAITING.equals(ev.getState())) {
System.out.println("waiting");
}
lk.lock();
even.signal();
lk.unlock();
}
class Evens extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Evens(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("even ph");
int cnt = 0;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
even.await();
System.out.println(cnt);
cnt += 2;
odd.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Odds extends Thread {
Lock lk;
Condition even;
Condition odd;
Phaser ph;
public Odds(Lock lk, Condition even, Condition odd, Phaser ph) {
this.lk = lk;
this.even = even;
this.odd = odd;
this.ph = ph;
}
#Override
public void run() {
System.out.println("odd ph");
int cnt = 1;
while (cnt < 20) {
try {
lk.lock();
ph.arrive();
odd.await();
System.out.println(cnt);
cnt += 2;
even.signal();
lk.unlock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
import java.awt.List;
import java.util.ArrayList;
import java.util.Random;enter code here
public class shared {
private int [] buffer;
private int capacity;
Object lock;//=new Object();
int count=0;
int i,j;
//int i=0,j=0;
public shared(int capacity){
this.capacity = capacity;
buffer = new int[capacity];
i=0;
j=0;
lock = new Object();
//for(int k=0;k<capacity;k++){
//buffer[k]=0;
//}
}
public void producer() throws InterruptedException {
//synchronized(lock){
while(true){
synchronized(lock){
Random rn = new Random();
int number = rn.nextInt(100);
Thread.sleep(1000);
while(count==capacity){
try{
System.out.println("BUffer is full");
lock.wait();
}catch(InterruptedException e){
}
//System.out.println("buffer is full");
}
System.out.println("producing" + number);
buffer[i] = number;
i = (i+1)%capacity;
count++;
lock.notifyAll();
}
}
}
public void consumer(){
//synchronized(lock){
while(true){
synchronized(lock){
while(count==0){
try{
lock.wait();
}catch(InterruptedException e){
}
}
//int a = buffer.get(0);
//buffer.remove(0);
int consumed = buffer[j];
System.out.println("consuming" + consumed);
j=(j+1)%capacity;
count--;
lock.notifyAll();
if((consumed%2)==0){
System.out.println("the number displayed by the consumer is " + consumed);
}
}
}
}
}
public class producer implements Runnable {
shared h;
public producer(shared s) {
// TODO Auto-generated constructor stub
h=s;
}
public void run(){
//for(int i=0;i<10;i++){
try {
h.producer();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class consumer implements Runnable {
shared h;
public consumer(shared s) {
// TODO Auto-generated constructor stub
h=s;
}
public void run(){
//for(int i=0;i<5;i++){
h.consumer();
}
}
public class implement {
public static void main(String [] args) throws InterruptedException{
shared s = new shared(10);
Thread pro1 = new Thread(new producer(s));
Thread con1 = new Thread(new consumer(s));
pro1.start();
con1.start();
pro1.join();
con1.join();
}
}
This is the entire code that I have written. The problem that I am getting is that my buffer is getting entirely full first then it is getting consumed. I want it to be consumed randomly i.e. when the first element fills up it might get get consumed or after 3-4 elements filled up.
I've reproduced your experiment and checked that, in fact, the producer thread fills the buffer before the consumer comes in. And that's because only when the buffer is full, the producer calls wait to give the consumers a chance.
The behaviour in a multi-threaded environment is always something random. Surely when the execution exits from the producer's synchronized block, the next iteration comes so quickly that it enters again in the block before other threads have a chance to.
If you want to produce and consume with an random ratio, I suggest you other means:
First, move the sleep out of the synchronized block.
Or else, do always a wait first-notify last into your producer loop, but performing a random number of inserts between them.
class NaiveSQ<E> {
boolean putting = false;
E item = null;
public synchronized E take() throws InterruptedException {
while (item == null)
wait();
E e = item;
item = null;
notifyAll();
return e;
}
public synchronized void put (E e) throws InterruptedException {
if (e == null)
return;
while (putting)
wait();
putting = true;
item = e;
notifyAll();
while (item != null)
wait();
putting = false;
notifyAll();
}
}
class Producer implements Runnable {
int id = -1;
int limit = 1;
Producer(int x) {
id = x;
}
public void run() {
System.out.printf("I am producer number %d\n", id);
for (int i=0; i<limit; i++) {
Integer I = new Integer(i);
try {
Test.queue.put(I);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
}
class Consumer implements Runnable {
int id = -1;
Consumer(int x) {
id = x;
}
public void run() {
try {
Integer I = Test.queue.take();
System.out.printf(
"I am consumer number %d - I read %d\n", id, I.intValue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
public class Test{
static NaiveSQ<Integer> queue;
public static void main (String [] args){
System.out.println("hello from Java");
Thread p = new Thread(new Producer(1));
p.start();
for (int i=0; i<1; i++) {
Thread c = new Thread(new Consumer(i));
c.start();
}
}
};
Also why does the exception contain null?
This is an implementation from http://www.cs.rice.edu/~wns1/papers/2006-PPoPP-SQ.pdf listing 3
I get output as
hello from Java
I am producer number 1
null
null
why do I get null?
You haven't initated the queue in your main method. I guess you get a NullPointerException since the queue object is never created and the Producer and Consumer refers to the queue which is null.
Even if you initialize the queue properly, still your implementation has a major issue. If the Consumer thread tries to take an item when the queue is empty (which is totally possible according to your code), then Consumer thread enters into an indefinite wait holding the lock to the object. Producer thread can never put an item to the queue. The whole thing will halt.
I have a pretty simple problem, in wich I try to exchange an object ( in this case an array of int) between two task : Producer and Consumer. The Producer class produces an array of int and than it tries to exchange it with the Consumer array ( which is an empty array) using an Exchanger object. But it seems that it doesn't work: when the Consumer tries to print the array, it gets nothing.
public class Producer implements Runnable{
private Exchanger<List<Integer>> exchanger;
private List<Integer> ints = new ArrayList<Integer>();
public Producer(Exchanger<List<Integer>> ex) {
this.exchanger = ex;
}
public void run() {
RandomGenerator.Integer gen = new RandomGenerator.Integer();
try{
while(!Thread.interrupted()) {
for (int i = 0;i < Test.LIST_SIZE;i++)
ints.add(gen.next());
exchanger.exchange(ints);
//for(Integer x : ints)
//System.out.print(" " + x);
//System.out.println();
}
}catch(InterruptedException e) {
System.out.println("Producer interrupted");
}
}
}
public class Consumer implements Runnable {
private Exchanger<List<Integer>> exchanger;
private List<Integer> ints = new ArrayList<Integer>();
public Consumer(Exchanger<List<Integer>> ex) {
this.exchanger = ex;
}
public void run() {
try{
while(!Thread.interrupted()) {
exchanger.exchange(ints);
System.out.println("Consumer:");
for(Integer x : ints) {
System.out.print(" " + x);
ints.remove(x);
}
System.out.println();
}
} catch(InterruptedException e) {
System.out.println("Consumer interrupted");
}
}
}
public class Test {
public static final int LIST_SIZE = 10;
public static void main(String[] args) throws InterruptedException {
ExecutorService exec = Executors.newCachedThreadPool();
Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
exec.execute(new Producer(exchanger));
exec.execute(new Consumer(exchanger));
TimeUnit.MILLISECONDS.sleep(5);
exec.shutdownNow();
}
If i uncomment the lines in Producer i see that the numbers generated are still there. So why does it not exchange the object?
The exchanger does not swap the references in place, but returns the exchanged object. So you should write something like:
List<Integer> received = exchanger.exchange(ints);
System.out.println("Consumer:");
for(Integer x : received) {
System.out.print(" " + x);
...
}
BTW, I don't think exchangers are appropriate for producer/consumers...
The exchange isn't magical; the Exchanger object can't replace the object references itself. The documentation tells us that calling the function returns the object that was provided by the other thread, once the exchange point was reached, which is how we "receive" it. I haven't actually done any of this, but I assume you're meant to assign this result back; i.e. ints = exchanger.exchange(ints); in both classes.