Така че моят проект е симулация тип карта. Имам клас дилър, играч и купчина. Купчината е споделен ресурс, където дилърът поставя една (не няколко, а само една) карта и играчът ще я вземе. Създавам две теми, една за дилър и една за играч. Дилърът трябва да изчака, докато бъде уведомен, че играчът е взел картата; след това той ще продължи да поставя нова карта. По същия начин Играчът ще изчака, докато бъде уведомен, че дилърът е поставил карта, и след това Играчът ще вземе картата.
Предполага се също така, че има механизъм, който и играчът, и дилърът ще използват, за да потвърдят, че имат право да поставят или вземат карта от купчината. Използвах булево; ако булевото е вярно или невярно, играчът или дилърът могат или не могат да бъдат допуснати да извършват съответните си действия.
Междувременно Играчът и Дилърът са настроени да спят за произволен интервал от време, когато след това ще се събудят и ще проверят дали могат да изпълняват своите действия. Ако не могат, ще изчакат, докато бъдат уведомени.
Въпросът ми включва методите за изчакване и уведомяване. Каква е разликата между чакане и сън? Как бих направил така, че играчът/дилърът да се събуди от сън и да бъде принуден да чака, докато бъде уведомен, ако не му е позволено да вземе/добави карта от купчината? Също така, правя ли изобщо синхронизацията правилно?
Съжалявам, че кодът ми е наистина объркан. Моля, поискайте разяснения.
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"
}
wait()
иnotify()
. Но е сложно и много лесно да го сбъркате. Бих например поставил цялата синхронизация и изчакване/уведомяване в класаHeap
, защото в момента нищо не гарантира, чеHeap.newCardChecker
ще бъде проверен, преди да поставите или вземете карта, и дори когато е отметнат, няма гаранция, че ще видите най-актуалната стойност. - person biziclop   schedule 20.01.2015