So I need to make an elevator simulator, and I was wondering how can I go about continuously generating people to call the elevator. I need this to go on forever. So basically a person is created and calls the elevator. All of these calls are kept track of but I think I need to keep track of the people who are actually on the elevator too.
I have a few classes Person, Elevator, ElevatorCall & ElevatorCallQueue.
In Person I have a run() method which basically makes an Elevator call with the current floor and destination floor and then I have a BlockingQueue that I put the call on. This run method just runs while true.
In ElevatorCall I just have getters and setters for the collection and destination floors
In ElevatorCallQueue, I have variables for MAX_CALLS and numberOfPeople.
I have a BlockingQueue<ElevatorCall> queue = new ArrayBlockingQueue<ElevatorCall>(MAX_CALLS)
and a List<Person>
I add people to the list and I run through the list and start the run() method on each person. Finally I create an elevator and provide the queue, and run it.
In Elevator I have the BlockingQueue<ElevatorCalls>. I have a while(true) here also, and inside it I make an ArrayList<ElevatorCall> and then I use the BlockingQueues drainTo method using the ArrayList<ElevatorCalls> as a parameter.
The rest of the run() method basically iterates through the array list and does what an elevator does, so It goes to the first pressed button, checks each floor for people and if it is a destination floor.
Right now I've gotton stuck and dont know where to go from here. I need to some how have People continiously added and calling the elevator, and have the Elevator wait if there is no more calls. Would appreciate it if anybody could help put me in the right direction.
Thanks
EDIT
Here is the code to the elevator class as somebody said I should post some code. However I'm not sure what code to post so I thought I'd just put in the entire class
I think everyone's jumped at the word concurrency very quickly - don't let it cloud your judgement. I can't speak on behalf your exact problem/criteria but an elevator goes about travelling to floors, with the only disturbance being a new person pressing a button. So, why not give elevator a method simulate(int time) that does this, and a method new_person(person p) which adds another person to the queue. Then just generate a random time interval, simulate the elevator, add a new person with random floor destination and source, and then repeat.
But you say it has to be concurrent -
Well your question seems to be where do the elevatorcalls come from?
This is an instance of the typical producer consumer pattern. What's that you ask?
Well the oracle documentation for BlockingQueue gives a better example than I ever could
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
Hmm.. Can you see how this relates to your problem? You've already solved half of it.
The Elevator acts as the consumer of elevatorCalls, you seem to be struggling with who produces them. This is a job for a new thread that runs an ElevatorCall producers. See if you can work the rest out.
Related
Trying to use n number of threads, where there are two different types of thread that needs to be being swapped between. So goes t1, x1, t2, x2, t3, x3.... where x and t are thread classes. I've been trying to use wait and notify but cant seem to get this to work. Or synchronisation.
All threads all need to access and modify the same list-array in their respective "turns" which i thought could be its own synchronised class, yet maybe an atomic variable would work also?
Any help is very appreciated.
"""
public String startGame(int threadNumbers, List<String> result, String fileLoc) throws IOException {
Players[] playerThreads = new Players[threadNumbers];
Card[] cardThreads = new Card[threadNumbers];
cardDeck cardD = new cardDeck(fileLoc);
for (int i = 0; i < (threadNumbers); i++) {
System.out.println(i);
playerThreads[i] = new Players(i+1, cardD);
if (i>0) {
playerThreads[i-1].next = cardThreads[i-0];
}
if (i==threadNumbers-1) {
playerThreads[i].next = cardThreads[0];
}
cardThreads[i] = new Card(i+1);
if (i>0) {
cardThreads[i-1].next = playerThreads[i-0];
}
if (i==threadNumbers-1) {
cardThreads[i].next = playerThreads[0];
}
new Thread(playerThreads[i]).start();
new Thread(cardThreads[i]).start();
Thread.yield();
Thread.yield();
}
synchronized (playerThreads[0]) {
playerThreads[0].notify();
"""
This is not working, but what needs to happen is they take a card from the deck in a looping way then start the game after they have a hand. The card threads also are just hands but are different as they dont "play" but just work.
Since this seems to be all in one (JVM) process, there's no need for multiple threading here: Just use a queue to track whose turn it is and who's turn it is next. After a player's turn, add them back to the end of the queue.
And actually, now that I think about it there's no reason this same solution couldn't work with multiple processes or over sockets.
Just use a queue
-- Edit --
So what you need is a class with a blocking method. For example
public class Player implements Runnable {
private Move nextMove;
public Move synchronized getMove() {
if (!nextMove) {
this.wait([add timeout if appropriate]);
}
Move next = nextMove;
nextMove = null;
return next;
}
public void run() {
while (true) {
Thread.sleep([someRandomTime]);
synchronized(this) {
if (nextMove == null) {
nextMove = new Move();
this.notify();
}
}
}
}
}
So still using your queue, you go through each Player and call getMove(), which will block until the player posts a move.
BTW, this kind of blocking is similar to how InputStream.read(buffer) works in sockets. The thread calling read waits until the other side of the stream sends some content.
-- Edit 2 --
And just as a reminder: Don't use synchronized, wait, notify or notifyAll on a Thread object.
Well, I am a student in the second semester, and now we are going trough threads. I mostly get it, but something is off about one of my exercises and I can't quite understand it.
"In a bakery shop, you often have to take a number when you arrive at the shop and then wait until it is your
turn (with the right number)."
Im going to copy-paste the methods in the monitor where I think the problem might be.
private NumberDispenser(){
nextNoToTake=1;
nextNoToServe=0;
}
public static NumberDispenser accessDispenser(){
if(theOne == null){
theOne = new NumberDispenser();
}
return theOne;
}
#Override
public synchronized void takeNextNumber() {
int currNo = nextNoToTake;
nextNoToTake++;
notifyAll();
System.out.println("No:"+currNo+" has been taken|nextNoToServe:"+nextNoToServe);
while(currNo != nextNoToServe)
{try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("No:"+currNo+" has been served");
notify();
}
#Override
public synchronized int nextCustomer() {//Serves the current customer and goes to the next one
System.out.println("Clerk is ready to deal with a new customer");
while((nextNoToServe)>=nextNoToTake-1)
try {
wait();
} catch (InterruptedException e) {}
nextNoToServe++;
notifyAll();
System.out.println("Now serving No:"+(nextNoToServe));
return nextNoToServe;
}
This is the monitor class. There are two more , for the Customer and for the Clerk , and one more for testing. The customer class has Thread.sleep to simulate time for browsing then goes into dispenser.takeNextNumber();, after which it should finish and the thread responsible for it should die by itself(in the main class).Clerk loops dispenser.nextCustomer() endlessly with a delay.The main method creates , in separate for loops, a number of customers and their threads , and a number of clerks and their threads.
///// This is copy pasted from the requirements.
Customer arrivals and clerk servings are simulated by threads.
Implement as a monitor a class NumberDispencer that implements the interface TakeANumber.
Hint: you could define the two instance variables
private int nextNumberToTake = 1;
private int nextNumberToServe = 1;
Implement two thread classes:
A thread class which simulates customer taking a number and being served
A thread class that simulates clerk serving, that is getting the next customer number and then make
service.
Implement a class with a main method to simulate a bakery shop with e.g. two serving clerks and ten
customers.
/////
I have almost fixed the code. The problem was in the condition of the while loops. Now it works almost as intended, but it skips over the first customer. Only the first customer is skipped, then it all goes how it should.
console output
I can see one place where it is broken.
Hint: Suppose that there is one server and one customer, and the server calls nextCustomer() before a customer arrives. What will wake it up when the customer arrives?
Also, this statement is a hack.
if (nextNoToServe == 0)
nextNoToServe = 1;
That should be dealt with by initializing the instance variables to appropriate values; e.g. in the constructor.
I am designing a system where there will be n producers and m consumers, where n and m are numbers, and n != m.
I wanted to design the system such a way that,
no producer should block other producer when producing
no consumer should block other consumer when consuming neither
producer nor consumer block each other while producing/consuming
For eg: in java if i use the synchronized key word, then it will be blocking the respective caller.
I am not sure what data structure and algorithm i should use to implement this system.
Can some one provide me help/pointers on this?
You probably want something like the ConcurrentLinkedQueue. The idea is that you create a single queue. Each of your n producers adds work items to the queue, and each of the m consumers reads work items from the queue. The producer is simply:
while not done
create work item
add work item to queue
The consumer is just as simple:
while not done
get next work item from queue
process work item
The ConcurrentLinkedQueue methods handle adding and removing items, synchronizing with the other producers and consumers as required.
The only real drawback is that you have to poll the queue to see if there are items. So you'll probably want an auto reset event that gets tripped whenever an item is added to the queue. For example:
add work item to queue
set ItemAvailable event
And the consumer would poll the queue and if no item is available, wait on the event:
while not done
while ((item = queue.poll) == null)
wait on ItemAvailable event
process item
Take a look at the example I linked. It really isn't difficult to use.
Depending on how much heavy lifting you need to do, and how well your solution need to scale, RxJava has a bit of a steep learning curve, but once you got past that it's probably the most elegant, scaling and performing solution.
Run all your producers in different threads, combine them with Merg(), move the consumers to there own thread on a unbound buffer with .observeOn(Scheduler.newThread()).
If you need something that runs well parallel on multiple systems, look at mapreduce.
If you need something at the complete other end of the spectrum (something simple), simply stick to a ConcurrentQueue. That doesn't support multicast, but at least solves the producer side of the problem.
You want an approach where every action would be atomic and uninterruptible, so yes, in my opinion the best approach would be to use synchronized modifier on methods to set the lock.
The other interesting approach would be to use atomic variables -> http://baptiste-wicht.com/posts/2010/09/java-concurrency-atomic-variables.html
That depends on your data in these producer/consumer structures.
use wait() and notify() for thread communication , u can create n producer and m consumer threads
class Q{
int n;
boolean value=false;
synchronized int get() {
if(!value)
try { wait(); }
catch(InterruptedException e)
{ System.out.println("thread interrupted"); }
System.out.println("Got : "+n);
value=false;
notify();
return n;}
synchronized void put(int n) {
if(value)
try { wait();}
catch(InterruptedException e)
{ System.out.println("thread interrupted"); }
this.n=n;
value=true;
System.out.println("Put : "+n);
notify();}}
class Producer implements Runnable{
Q q;
Producer(Q q){
this.q=q;
new Thread(this,"Producer").start();}
public void run(){
int i=0;
while(true)
{
q.put(i++);}}
}
class Consumer implements Runnable{
Q q;
Consumer(Q q) {
this.q=q;
new Thread(this,"Consumer").start();}
public void run(){
while(true)
{
q.get();
}}}
class PCFixed
{
public static void main(String ar[])
{
Q q=new Q();
new Producer(q);
new Consumer(q);
System.out.println("PRESS CONTROL-C TO STOP");
}
}
it goes to infinity, change that based on ur requirements
So I am working on this program that simulates a day at work and each worker is its own thread. I'm trying to implement meetings where the workers attend meetings but the meetings do not start until everyone that is supposed to be at the meeting has arrived. So I have this method for attending the meeting.
public void attendMeeting(Employee worker){
this.cdStart.countDown();
worker.meetingWait();
try {
this.cdStart.await();
worker.meetingStart(this.length);
if(this.attendees.get(0).equals(worker)){
this.room.exit();
} // end if
} // end try
catch (InterruptedException err) {
// Do Nothing
} // end catch
} // end method attendMeeting
The worker parameter being an instance of the Employee class that extends Thread and this.cdStart is the CountDownLatch. However, when running this with a meeting of four employees, only one employee seems to be able to get in, decrement the count, and hit the await() call. None of the other worker threads seem to be able to enter it. I did notice that a lot of the online examples of use pass the CountDownLock object to the threads themselves to handle. Is there a reason why this would not work instead?
I am assuming you are having a single thread pass in an Employee Thread object. That single thread will be waiting indefinitely until the N number of parties arrive (you need an individual thread for each Employee instance aside from the Employee thread). This means that if only one thread is continuously passing the Employee/Thread you will never get more then one Employee waiting at the meeting.
This thread should instead, at best, signal the Employee threads to attend the Meeting.
You should have the latch in the Meeting class and have them await on that latch. This also requires a slight restructure of the way it works.
You pass the Meeting instance into the Employee to have that thread wait.
public Employee extends Thread{
//define this at some point whether in constructor or a
//means of notifying the thread to attend the meeting
private Meeting meeting;
public void run(){
//do some stuff until this employee is ready to go to a meeting
meeting.waitForAllOthersToArrive();
}
}
public class Meeting{
CountDownLatch latch = new CountDownLatch(numberOfEmployees);
public void waitForAllOthersToArrive(){
latch.countDown();
latch.await();
}
}
What I would suggest for this however is a CylicBarrier. Though you wouldn't be re using it, the way the CyclicBarrier works fits better what you're trying to do, the Meeting class would then look like
public class Meeting{
CylicBarrier barrier = new CylicBarrier(numberOfEmployees);
public void waitForAllOthersToArrive(){
barrier.await(); //when await() is called numberOfEmployees then all waiting threads will awake
}
}
This piece of code:
synchronized (mList) {
if (mList.size() != 0) {
int s = mList.size() - 1;
for (int i = s; i > 0; i -= OFFSET) {
mList.get(i).doDraw(canv);
}
getHead().drawHead(canv);
}
}
Randomly throws AIOOBEs. From what I've read, the synchronized should prevent that, so what am I doing wrong?
Edits:
AIOOBE = Array Index Out Of Bounds Exception
The code's incomplete, cut down to what is needed. But to make you happy, OFFSET is 4, and just imagine that there is a for-loop adding a bit of data at the beginning. And a second thread reading and / or modifying the list.
Edit 2:
I've noticed it happens when the list is being drawn and the current game ends. The draw-thread hasn't drawn all elements when the list is emptied. Is there a way of telling the game to wait with emtying the list untill it's empty?
Edit 3:
I've just noticed that I'm not sure if this is a multi-threading problem. Seems I only have 2 threads, one for calculating and drawing and one for user input.. Gonna have to look into this a bit more than I thought.
What you're doing looks right... but that's all:
It doesn't matter on what object you synchronize, it needn't be the list itself.
What does matter is if all threads always synchronize on the same object, when accessing a shared resource.
Any access to SWING (or another graphic library) must happen in the AWT-Thread.
To your edit:
I've noticed it happens when the list is being drawn and the current game ends. The draw-thread hasn't drawn all elements when the list is emptied. Is there a way of telling the game to wait with emtying the list untill it's empty?
I think you mean "...wait with emptying the list until the drawing has completed." Just synchronize the code doing it on the same lock (i.e., the list itself in your case).
Again: Any access to a shared resource must be protected somehow. It seems like you're using synchronized just here and not where you're emptying the list.
The safe solution is to only allow one thread to create objects, add and remove them from a List after the game has started.
I had problems myself with random AIOOBEs erros and no synchornize could solve it properly plus it was slowing down the response of the user.
My solution, which is now stable and fast (never had an AIOOBEs since) is to make UI thread inform the game thread to create or manipulate an object by setting a flag and coordinates of the touch into the persistent variables.
Since the game thread loops about 60 times per second this proved to be sufficent to pick up the message from the UI thread and do something.
This is a very simple solution and it works great!
My suggestion is to use a BlockingQueue and I think you are looking for this solution also. How you can do it? It is already shown with an example in the javadoc :)
class Producer implements Runnable {
private final BlockingQueue queue;
Producer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { queue.put(produce()); }
} catch (InterruptedException ex) { ... handle ...}
}
Object produce() { ... }
}
class Consumer implements Runnable {
private final BlockingQueue queue;
Consumer(BlockingQueue q) { queue = q; }
public void run() {
try {
while (true) { consume(queue.take()); }
} catch (InterruptedException ex) { ... handle ...}
}
void consume(Object x) { ... }
}
class Setup {
void main() {
BlockingQueue q = new SomeQueueImplementation();
Producer p = new Producer(q);
Consumer c1 = new Consumer(q);
Consumer c2 = new Consumer(q);
new Thread(p).start();
new Thread(c1).start();
new Thread(c2).start();
}
}
The beneficial things for you are, you need not to worry about synchronizing your mList. BlockingQueue offers 10 special method. You can check it in the doc. Few from javadoc:
BlockingQueue methods come in four forms, with different ways of handling operations that cannot be satisfied immediately, but may be satisfied at some point in the future: one throws an exception, the second returns a special value (either null or false, depending on the operation), the third blocks the current thread indefinitely until the operation can succeed, and the fourth blocks for only a given maximum time limit before giving up.
To be in safe side: I am not experienced with android. So not certain whether all java packages are allowed in android. But at least it should be :-S, I wish.
You are getting Index out of Bounds Exception because there are 2 threads that operate on the list and are doing it wrongly.
You should have been synchronizing at another level, in such a way that no other thread can iterate through the list while other thread is modifying it! Only on thread at a time should 'work on' the list.
I guess you have the following situation:
//piece of code that adds some item in the list
synchronized(mList){
mList.add(1, drawableElem);
...
}
and
//code that iterates you list(your code simplified)
synchronized (mList) {
if (mList.size() != 0) {
int s = mList.size() - 1;
for (int i = s; i > 0; i -= OFFSET) {
mList.get(i).doDraw(canv);
}
getHead().drawHead(canv);
}
}
Individually the pieces of code look fine. They seam thread-safe. But 2 individual thread-safe pieces of code might not be thread safe at a higher level!
It's just you would have done the following:
Vector v = new Vector();
if(v.length() == 0){ v.length() itself is thread safe!
v.add("elem"); v.add() itself is also thread safe individually!
}
BUT the compound operation is NOT!
Regards,
Tiberiu