Reputation: 77
So my project is a card type simulation. I have a Dealer, Player, and Heap class. The heap is a shared resource where the dealer places one(not multiple, just one) card and the player will pick it up. I create two threads, one for a Dealer and one for a Player. The dealer is supposed to wait until he is notified that the player has picked up the card; then he will proceed to place a new card down. Similarly, the Player will wait until he is notified that the dealer has placed a card down, and then the Player will pick the card up.
There is also supposed to be a mechanism that both the Player and the Dealer will use to confirm that they are allowed to put or take a card from the Heap. I used a boolean; if the boolean is true or false, the Player or the Dealer could or could not be allowed to do their corresponding actions.
In the mean time, the Player and the Dealer are set to sleep for a random time interval, when they will then wake up and check to see if they can run their actions. If they cannot, they would wait until they are notified.
My question involves the wait and notify methods. What is the difference between wait and sleep? How would I make is to that the Player/Dealer would wake up from a sleep, and they are forced to wait until they are notified, if they are not allowed to take/add a card from the heap? Also, am I even doing the synchronization properly?
Sorry that my code is really messy. Please ask for clarifications.
import java.util.ArrayList;
public class Heap {
static String topCard;
static boolean newCardChecker = false;
public Heap(){
}
public synchronized static void putOnHeap(String Card){
topCard = Card;
newCardChecker = true;
}
public synchronized static String takeFromHeap(){
newCardChecker = false;
return topCard;
}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random;
public class Dealer implements Runnable {
String[] deck = {"2 Hearts", "3 Hearts", "4 Hearts", "5 Clubs", "6 Clubs", "7 Clubs",
"8 Hearts", "9 Hearts", "10 Hearts" , "10 Spades"};
ArrayList<String> myHand = new ArrayList<>();
Heap theHeap;
public Dealer(Heap heap){
theHeap = heap;
for(int i = 0; i < deck.length; i++){ //adds deck to dealer's hand
myHand.add(deck[i]);
}
}
public void run(){
//synchronized(theHeap){
while(myHand.size() != 0){ //repeat until dealer's hand is empty
if(Heap.newCardChecker != false){
try{
Thread.currentThread().wait();
}catch(InterruptedException e){
}
theHeap.putOnHeap(myHand.get(0));
System.out.println("Placed card " + myHand.get(0) + " onto heap");
myHand.remove(0); //although dealer's cards in hand is being removed, the dealer had
//the same cards as deck so I print out the deck contents at the end
Thread.currentThread().notify();
}
try{
Thread.currentThread().sleep(3000 + (int)Math.random() * 10000);
}catch(InterruptedException e){
}
}
//}
System.out.println("Hello, I am a dealer. Here is my hand: " + Arrays.deepToString(deck));
}
//While not last card, put a card on heap. sleep for a rand time
//print "put card x on heap"
public static void main(String[] args){
Heap heap = new Heap();
Thread t1 = new Thread(new Dealer(heap));
Thread t2 = new Thread(new Player(heap));
//Thread t3 = new Thread(new Heap());
t1.start();
t2.start();
}
}
import java.util.ArrayList;
public class Player implements Runnable {
ArrayList<String> myHand = new ArrayList<String>();
Heap theHeap;
public Player(Heap heap){
theHeap = heap;
}
public void run(){
//synchronized(theHeap){
while(myHand.size() != 10){
try{
Thread.currentThread().sleep(3000 + (int)Math.random() * 10000);
}catch(InterruptedException e){
}
if(Heap.newCardChecker != true){
try{
Thread.currentThread().wait();
}catch(InterruptedException e){
//System.err.println("Exception caught");
}
myHand.add(theHeap.takeFromHeap());
System.out.println("Took card " + myHand.get(myHand.size() - 1) + " from heap");
Thread.currentThread().notify();
}
}
System.out.println("Hello, I am a player. Here is my hand: " + myHand.toString());
}
//}
//While less than or equal to 10 card, take card from heap. Then sleep.
//"print took card x from heap"
}
Upvotes: 0
Views: 98
Reputation: 27115
One way to solve your problem would be to make the Heap
be an ArrayBlockingQueue with a fixed-capacity of one element. The Dealer
would simply loop put()
ting cards onto the heap, and the Player
would loop, take()
ing cards from the heap.
The Dealer would automatically block (i.e., wait) in the put()
call whenever the heap already had a card in it, and the Player would block in the take()
call whenever the heap was empty.
You could put sleep()
calls into either loop to simulate the Dealer and the Player taking time.
Regarding the difference between sleep()
and wait()
;
You could achieve the exact same effect as sleept(t)
by calling foo.wait(t)
on an object foo
that never gets notified. So, technically, sleep()
is redundant: We could all get along without it.
But names are important. When I see foo.wait()
in a program, I expect that the caller is waiting for some other thread to do something related to the foo
object, and when I see sleep()
I know that the caller is just killing some time.
Upvotes: 1