I'm writing a small program to help me learn some multithreading in java, and I'm stuck on how to implement some scenario.
The program simulates a gas station that also has a coffee house in it.
I want to be able to create the following scenario:
add a person to a gas pump queue.
at the same time add a person to a cashier queue in the coffee house.
if the person's turn in the pump queue arrives before the turn in the cashier queue, allow him to choose what to do (stay in cashier queue and quit the pump queue or the other way around).
How can I jump between these 2 states?
So far I have this:
The Person class
public class Person implements Runnable {
private GasPump pump;
private Cashier cashier;
...
public void pumpGas() throws InterruptedException {
synchronized (this) {
pump.addCarToQueue(this);
wait();
}
synchronized (pump) {
sleep((long) (Math.random() * 5000));
pump.notify();
}
}
public void buyCoffee() throws InterruptedException {
synchronized (this) {
cashier.addCustomerToQueue(this); // standing inline
wait();
}
synchronized (cashier) {
sleep((long) (Math.random() * 5000)); // paying at cashier
cashier.notify();
}
}
...
}
The GasPump class
public class GasPump implements Runnable {
private Queue<Person> cars;
...
#Override
public void run() {
while (gasStation.isOpen()) {
if (!cars.isEmpty()) {
Car firstCar = cars.poll();
if (firstCar != null) {
synchronized (firstCar) {
firstCar.notifyAll();
}
} else {
// ?
}
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
...
}
And the Cashier class
public class Cashier implements Runnable {
private Queue<Person> customers;
...
#Override
public void run() {
while(coffeeHouse.isOpen()){
if(!customers.isEmpty()){
Car firstCustomer = customers.poll();
if(firstCustomer != null){
synchronized (firstCustomer) {
firstCustomer.notifyAll();
}
}
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
...
}
You should avoid using wait and notify as it is difficult to use them correctly and efficiently - use the classes from java.util.concurrent instead.
What I would do: add two boolean flags to your Person: hasPumped and hasShopped - once a person pumps their gas or shops then you set the appropriate flag to true.
Replace your Queues with BlockingQueues (probably the LinkedBlockingQueue is appropriate here) - this is a thread-safe queue, and you can call take on it in order to block until the queue is non-empty (rather than polling and then sleeping if the queue is empty). If you prefer to poll and sleep then you may want to use a ConcurrentLinkedQueue instead, though I advise that you use take on a BlockingQueue instead.
Add a Person to the GasPump and Cashier queues. When the person is removed from the queue via take or poll, then check its hasPumped or hasShopped flag to determine if any additional action is needed, for example if the Cashier takes the person and hasPumped is true then there's no need to ask the Person if they want to continue waiting in the gas queue since they've already finished pumping.
If the person chooses to quit a queue, then call remove(person) on the appropriate queue.
When the person finishes pumping gas then put them in the cashier queue if their hasShopped flag is false, and likewise put them in the gas queue when they've finished shopping if their hasPumped flag is false.
You shouldn't need any synchronized blocks or methods with this implementation.
public class Person implements Runnable {
private GasPump pump;
private Cashier cashier;
private boolean hasPumped, hasShopped, readyToPump, readyToShop;
private Thread thread;
public void run() {
thread = Thread.getCurrentThread();
while(!hasPumped && !hasShopped) {
try {
readyToPump = false;
readyToShop = false;
if (!hasPumped)
pumpGas();
if(!hasShopped)
buyCoffee();
thread.sleep(FOREVER);
} catch (InterruptedException ex) {
// check flags to see what to do next
}
}
}
public void pumpGas() {
pump.addCarToQueue(this);
}
public void buyCoffee() {
cashier.addCustomerToQueue(this);
}
public void setReadyToPump() {
readyToPump = true;
thread.interrupt();
}
public void setReadyToShop() {
readyToShop = true;
thread.interrupt();
}
}
public class GasPump implements Runnable {
private BlockingQueue<Person> cars = new LinkedBlockingQueue<>();
#Override
public void run() {
while (gasStation.isOpen()) {
Person person = cars.take();
person.setReadyToPump();
}
// clean up persons in queue
}
}
public class Cashier implements Runnable {
private BlockingQueue<Person> customers = new LinkedBlockingQueue();
#Override
public void run() {
while(coffeeHouse.isOpen()){
Person person = customers.take();
person.setReadyToShop();
}
// clean up persons in queue
}
}
Related
So my task is this:
Instantiate two object of the same class
Provide a constructor argument, to designate a thread as even and another as odd .
Start both threads right one after other
Odd thread prints odd numbers from 0 to 1000
Even thread prints even numbers from 0 to 1000
However they should be in sync the prints should be 1 , 2 , 3 , 4 .....
One number on each line
However I can't seem to get the locks to release correctly. I've tried reading some of the similar problems on here but they all use multiple classes. What am I doing wrong?
Edit: My main class is doing this -
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
and my output is -
odd: 1
even: 2
...
public class NumberPrinter extends Thread {
private String name;
private int starterInt;
private boolean toggle;
public NumberPrinter(String name) {
super.setName(name);
this.name=name;
if(name.equals("odd")) {
starterInt=1;
toggle = true;
}
else if(name.equals("even")) {
starterInt=2;
toggle = false;
}
}
#Override
public synchronized void run() {
int localInt = starterInt;
boolean localToggle = toggle;
if(name.equals("odd")) {
while(localInt<1000) {
while(localToggle == false)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = false;
notify();
}
}
else {
while(localInt<1000) {
while(localToggle == true)
try {
wait();
}catch(InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println(name+": "+localInt);
localInt +=2;
localToggle = true;
notify();
}
}
}
}
The key problem here is that the two threads have no way to coordinate with each other. When you have a local variable (localToggle in this case) nothing outside the method can observe or alter its value.
If you share one object with both threads, however, its state can change, and if used correctly, those state changes will be visible to both threads.
You will see examples where the shared object is an AtomicInteger, but when you use synchronized, wait() and notify(), you don't need the extra concurrency overhead built into the atomic wrappers.
Here's a simple outline:
class Main {
public static main(String... args) {
Main state = new Main();
new Thread(new Counter(state, false)).start();
new Thread(new Counter(state, true)).start();
}
int counter;
private static class Counter implements Runnable {
private final Main state;
private final boolean even;
Counter(Main state, boolean even) {
this.state = state;
this.even = even;
}
#Override
public void run() {
synchronized(state) {
/* Here, use wait and notify to read and update state.counter
* appropriately according to the "even" flag.
*/
}
}
}
}
I'm not clear whether using wait() and notify() yourself is part of the assignment, but an alternative to this outline would be to use something like a BlockingQueue to pass a token back and forth between the two threads. The (error-prone) condition monitoring would be built into the queue, cleaning up your code and making mistakes less likely.
I finally got it working in a way that meets the standards required by my assignment.
Thank you all for your input. I'll leave the answer here for anyone who might need it.
public class Demo {
public static void main(String[] args) {
NumberPrinter oddPrinter = new NumberPrinter("odd");
NumberPrinter evenPrinter = new NumberPrinter("even");
oddPrinter.start();
evenPrinter.start();
System.out.println("Calling thread Done");
}
public class NumberPrinter extends Thread {
private int max = 1000;
static Object lock = new Object();
String name;
int remainder;
static int startNumber=1;
public NumberPrinter(String name) {
this.name = name;
if(name.equals("even")) {
remainder=0;
}else {
remainder=1;
}
}
#Override
public void run() {
while(startNumber<max) {
synchronized(lock) {
while(startNumber%2 !=remainder) {
try {
lock.wait();
}catch(InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name+": "+startNumber);
startNumber++;
lock.notifyAll();
}
}
}
}
I have Written program which solves the below problem but I am trying to make it STARVATION FREE but I am not sure how to implement it. So, each north farmers and south farmers get an equal amount of chance to cross the bridge.
Scenario
A single-lane bridge connects the two Vermont villages of North Tunbridge and South Tunbridge. Farmers in the two villages use this bridge to deliver their produce to the neighboring town. The bridge can become deadlocked if both a northbound and a southbound farmer get on the bridge at the same time (Vermont farmers are stubborn and are unable to back up.)
Here what I have tried:
package threading.practice;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
public class SingleLaneBridge {
public static void main(String[] args)
{
final Bridge bridge = new Bridge();
Thread thNorthbound = new Thread( new Runnable() {
#Override
public void run() {
while(true)
{
Farmer farmer = new Farmer(bridge);
Thread th = new Thread(farmer);
farmer.setName("North Farmer : "+th.getId());
th.start();
try
{
TimeUnit.SECONDS.sleep((long)(Math.random()*10));
}
catch(InterruptedException iex)
{
iex.printStackTrace();
}
}
}
});
Thread thSouthbound = new Thread( new Runnable() {
#Override
public void run() {
while(true)
{
Farmer farmer = new Farmer(bridge);
Thread th = new Thread(farmer);
farmer.setName("South Farmer : "+th.getId());
th.start();
try
{
TimeUnit.SECONDS.sleep((long)(Math.random()*10));
}
catch(InterruptedException iex)
{
iex.printStackTrace();
}
}
}
});
thNorthbound.start();
thSouthbound.start();
}
}
class Bridge
{
private final Semaphore semaphore;
public Bridge()
{
semaphore = new Semaphore(1);
}
public void crossBridge(Farmer farmer)
{
try
{
System.out.printf("Farmer %s is trying to cross the bridge.\n",farmer.getName());
semaphore.acquire();
System.out.printf("Farmer %s is crossing the bridge.\n",farmer.getName());
long duration = (long)(Math.random() * 10);
TimeUnit.SECONDS.sleep(duration);
}
catch(InterruptedException iex)
{
iex.printStackTrace();
}
finally
{
System.out.printf("Farmer %s has crossed the bridge.\n",farmer.getName());
semaphore.release();
}
}
}
class Farmer implements Runnable
{
private String name;
private Bridge bridge;
public Farmer(Bridge bridge)
{
this.bridge = bridge;
}
public void run()
{
bridge.crossBridge(this);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The java.util.concurrent.Semaphore has a constructor that takes a fairness flag. When this is set it queues acquires and guarantees that they are executed in fifo order.
The doc has a note on the use of the flag:
Generally, semaphores used to control resource access should be initialized as fair, to ensure that no thread is starved out from accessing a resource. When using semaphores for other kinds of synchronization control, the throughput advantages of non-fair ordering often outweigh fairness considerations.
I searched for an answer to this question on SO and Google but couldn't find a proper solution so far.
I'm currently working on a LayerManager in a graph routing problem. The manager is responsible for providing and resetting a fixed set of layers.
I wanted to implement the Consumer-Producer pattern with a blocking list, so that incoming routing requests are blocked as long no free layer is available. So far I only found a blocking queue but since we don't need FIFO, LIFO but random access a queue doesn't really work. To be a little more precise, something like this should be possible:
/* this should be blocking until a layer becomes available */
public Layer getLayer(){
for ( Layer layer : layers ) {
if ( layer.isUnused() && layer.matches(request) )
return layers.pop(layer);
}
}
Is there any way to achieve this?
What you are looking for is called "Semaphore".
Create a Semaphore class
Add it as a field to Layer class
Example
public class Semaphore
{
private boolean signal = false;
public synchronized boolean take()
{
if(this.signal==true)
return false; //already in use
this.signal = true;
this.notify();
return true;
}
public synchronized void release() throws InterruptedException
{
while(!this.signal) wait();
this.signal = false;
}
public boolean isUnused()
{
return !signal ;
}
}
//2.
class Layer
{
Semaphore sem =null;
/*your code*/
/*sem = new Semaphore(); in constructors*/
public boolean take()
{
return this.sem.take();
}
public void release()
{
this.sem.release();
}
public Layer getLayer()
{
for ( Layer layer : layers )
{
if ( layer.matches(request) && layer.take())
return layer;
}
return null;
}
}
Synchronized methods handle access concurrence
3. Loop over getLayer until
Layer l=null;
while(l==null)
{
l= getlayer();
Thread.sleep(100); //set time
}
// continue
// do not forget to release the layer when you are done
Try to use Map<String, BlockingQueue<Layer>>. The idea is to hold free Layers inside of BlockingQueue. Every request has his own queue.
public class LayerQueue {
Map<String, BlockingQueue<Layer>> freeLayers = Collections.synchronizedMap(new HashMap<String, BlockingQueue<Layer>>());
public LayerQueue() {
//init QUEUEs
freeLayers.put("request-1", new ArrayBlockingQueue<Layer>(1)); // one to one...
freeLayers.put("request-2", new ArrayBlockingQueue<Layer>(1));
[...]
}
public void addUnusedLayer(Layer layer, String request) {
BlockingQueue<Layer> freeLayersForRequest = freeLayers.get(request);
freeLayersForRequest.add(layer);
}
public Layer getLayer(String request) {
BlockingQueue<Layer> freeLayersForRequest = freeLayers.get(request);
try {
return freeLayersForRequest.take(); // blocks until a layer becomes available
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
}
I am not quite sure I understand your need correctly, but you could consume a blocking queue and put the results into a list. If an appropriate layer is not found in the list, call wait() and check again when a new item is added to the list from the queue. This sounds like it could work conceptually, even if the code below doesn't get it right (I am quite sure this is not quite properly synchronized)
public class PredicateBlockingQueue<Product> {
private final List<Product> products = new LinkedList<Product>();
private final BlockingQueue<Product> queue;
private final Thread consumer;
public PredicateBlockingQueue(int capacity) {
queue = new ArrayBlockingQueue<Product>(capacity);
consumer = new Thread() {
#Override
public void run() {
while(!Thread.interrupted()) {
try {
products.add(queue.take());
synchronized(queue) {
queue.notifyAll();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
};
consumer.start();
}
public void put(Product product) throws InterruptedException {
queue.put(product);
}
public Product take(Predicate<Product> predicate) throws InterruptedException {
Product product;
while((product=find(predicate))==null) {
synchronized(queue) {
queue.wait();
}
}
return product;
}
private synchronized Product find(Predicate<Product> predicate) {
Iterator<Product> it = products.iterator();
while(it.hasNext()) {
Product product = it.next();
if(predicate.test(product)) {
it.remove();
return product;
}
}
return null;
}
OK, So I have these classes that extend Thread, what I'm supposed to do is:
Let all alumns arrive.
When alumns arrive they say 'Hi'.
If the teacher arrives but not all of the Alumns have arrived then he should wait() for them.
Alumns should notify() the teacher when they're all there.
An alumn is a Thread initialized with boolean value 0.
A teacher is a Thread initialized with boolean value 1.
Person/Greeting Code
public class Person extends Thread {
private Thread t;
private String threadName;
boolean id;
Greeting greeting;
public Person(String name,boolean tipo,int n){
this.threadName = name;
this.id=tipo;
greeting =new Greeting();
}
#Override
public void run() {
if(id==false) {
try {
greeting.alumn(threadName);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
else{
try {
greeting.teacher(threadName);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public void start()
{
System.out.println("Starting "+ threadName);
if(t==null)
{
t=new Thread(this,threadName);
t.start();
}
}
}
class Greeting {
public void alumn(String s) throws InterruptedException{
System.out.println(s);
synchronized (this){
System.out.println("Alumn: "+s);
notifyAll();
}
}
public synchronized void teacher(String s) throws InterruptedException {
wait();
System.out.println(s);
}
}
Main class
public class ClassRoom {
public static void main(String [] args) {
Person francisco = new Person("Francisco",false,1);
Person jesus = new Person("Jesus", false,2);
Person alberto = new Person("Alberto",false,3);
Person karla = new Person("Karla",false,4);
Person maestro = new Person("Professor",true,0);
francisco.start();
jesus.start();
alberto.start();
karla.start();
maestro.start();
}
}
The problem:
If the teacher arrives first he goes to wait()...then alumns arrive but he never wakes up.
If the teacher doesn't arrive first, he still never wakes up!
How to fix this?
If the teacher arrives first he goes to wait()...then alumns arrive
but he never wakes up.
All you Persons instantiate their own Greeting, which synchronzizes on this and therefore also waits/notifies on this. Each Person uses its own semaphore, which is not what you want. You should synchronize on the same object (perhaps Greeting.class) for all instances.
If the teacher doesn't arrive first, he still never wakes up! How to fix this?
Simply check if all alumns are there. If yes greet, else wait for notify. Afterwards check again. The check has to be part of the synchronized block to avoid race conditions.
To wait until all threads has arrived to certain point, consider using CyclicBarrier.
I would like to create a class that runs something (a runnable) at regular intervals but that can be awaken when needed. If I could encapsulate the whole thing I would like to expose the following methods:
public class SomeService implements Runnable {
public run() {
// the code to run at every interval
}
public static void start() { }
public static void wakeup() { }
public static void shutdown() { }
}
Somehow I've gotten this far. But I'm not sure if this is the correct approach.
public class SomeService implements Runnable {
private static SomeService service;
private static Thread thread;
static {
start();
}
private boolean running = true;
private SomeService() {
}
public void run() {
while (running) {
try {
// do what needs to be done
// perhaps peeking at a blocking queue
// or checking for records in a database
// trying to be independent of the communication
System.out.println("what needs to be done");
// wait for 15 seconds or until notify
synchronized (thread) {
try {
thread.wait(15000);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
private static void start() {
System.out.println("start");
service = new SomeService();
thread = new Thread(service);
thread.setDaemon(true);
thread.start();
}
public static void wakeup() {
synchronized (thread) {
thread.notify();
}
}
public static void shutdown() {
synchronized (thread) {
service.running = false;
thread.interrupt();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("shutdown");
}
public static void main(String[] args) throws IOException {
SomeService.wakeup();
System.in.read();
SomeService.wakeup();
System.in.read();
SomeService.shutdown();
}
}
I'm concerned that the variables should be declared volatile. And also concerned that I should check in the "what needs to be done part" for thread.isInterrupted(). Does this seem like the right approach? Should I translate this to executors? How can I force a run on a scheduled executor?
EDIT
After experimenting with the executor, it seems that this approach seems reasonable. What do you think?
public class SomeExecutorService implements Runnable {
private static final SomeExecutorService runner
= new SomeExecutorService();
private static final ScheduledExecutorService executor
= Executors.newSingleThreadScheduledExecutor();
// properties
ScheduledFuture<?> scheduled = null;
// constructors
private SomeExecutorService() {
}
// methods
public void schedule(int seconds) {
scheduled = executor.schedule(runner, seconds, TimeUnit.SECONDS);
}
public void force() {
if (scheduled.cancel(false)) {
schedule(0);
}
}
public void run() {
try {
_logger.trace("doing what is needed");
} catch (Exception e) {
_logger.error("unexpected exception", e);
} finally {
schedule(DELAY_SECONDS);
}
}
// static methods
public static void initialize() {
runner.schedule(0);
}
public static void wakeup() {
runner.force();
}
public static void destroy() {
executor.shutdownNow();
}
}
For starters - you probably don't want to implement Runnable yourself; you should take in a Runnable. You should only implement Runnable if you expect your class to be passed to others to execute.
Why not just wrap a ScheduledExecutorService? Here's a quick (very poor, but ought to be functional) implementation.
public class PokeableService {
private ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
private final Runnable codeToRun;
public PokeableService (Runnable toRun, long delay, long interval, TimeUnit units) {
codeToRun = toRun;
service.scheduleAtFixedRate(toRun, delay, interval, units);
}
public void poke () {
service.execute(codeToRun);
}
}
The variables do not need to be volatile since they are read and modified in a synchronized block.
You should use a different object for the lock then the thread, since the Thread class does it's own synchronization.
I would recommend using a single threaded ScheduledExecutorService and remove sleeping. Then if you want to run the task during the current sleep period, you can submit it to the executor again for a single time run. Just use the execute or submit methods in ExecutorService which ScheduledExecutorService extends.
About checking for isInterrupted, you should do this if the do work portion can take a lot of time, can be cancelled in the middle, and is not calling methods that block and will throw an interrupted exception any ways.
Using wait/notify should be a more efficient method. I also agree with the suggestion that using 'volatile' is not necessary and synchronizing on an alternative object would be wise to avoid conflicts.
A few other suggestions:
Start the thread elsewhere, starting from a static block is not good practice
Putting the execute logic in an "execute()" method or similar would be desirable
This code implements the above suggestions. Note also that there is only the one thread performing the SomeService execution logic and that it will occur INTERVAL milliseconds after the time it last completed. You should not get duplicate executions after a manually triggered wakeUp() call.
public class SomeService implements Runnable {
private static final INTERVAL = 15 * 1000;
private Object svcSynchronizer = new Object();
private boolean running = true;
private SomeService() {
}
public void run() {
while (running) {
try {
// do what needs to be done
// perhaps peeking at a blocking queue
// or checking for records in a database
// trying to be independent of the communication
System.out.println("what needs to be done");
// wait for 15 seconds or until notify
try {
svcSynchronizer.wait(INTERVAL);
} catch (InterruptedException e) {
// ignore interruptions
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void wakeUp() {
svcSynchronizer.notifyAll();
}
public void shutdown() {
running = false;
svcSynchronizer.notifyAll();
}
}