Ждать и уведомлять методы в синхронизации?
Так что мой проект - симуляция карточного типа. У меня есть класс Дилер, Игрок и Куча. Куча - это общий ресурс, где дилер кладет одну (не множественную, а только одну) карту, и игрок забирает ее. Я создаю две темы, одну для дилера и одну для игрока. Предполагается, что дилер подождет, пока ему не сообщат, что игрок забрал карту; Затем он приступит к установке новой карты вниз. Точно так же Игрок будет ждать, пока не получит уведомление о том, что дилер положил карту вниз, а затем Игрок заберет карту.
Предполагается также механизм, который игрок и дилер будут использовать для подтверждения того, что им разрешено положить или взять карту из кучи. Я использовал логическое значение; Если логическое значение истинно или ложно, Игроку или Дилеру может или не может быть разрешено выполнять свои соответствующие действия.
В то же время, Игрок и Дилер находятся в спящем режиме в течение произвольного интервала времени, когда они затем проснутся и проверит, могут ли они выполнить свои действия. Если они не могут, они будут ждать, пока их не уведомят.
Мой вопрос связан с методами ожидания и уведомления. В чем разница между ожиданием и сном? Как бы я поступил так, чтобы Игрок / Дилер проснулся ото сна, и они вынуждены ждать, пока их не уведомят, если им не позволено взять / добавить карту из кучи? Кроме того, я даже делаю синхронизацию должным образом?
Извините, что мой код действительно грязный. Пожалуйста, попросите разъяснений.
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"
}
1 ответ
Одним из способов решения вашей проблемы было бы сделать Heap
быть ArrayBlockingQueue с фиксированной емкостью одного элемента. Dealer
будет просто петля put()
карты в кучу, и Player
будет цикл, take()
Карты из кучи.
Дилер будет автоматически блокировать (то есть ждать) в put()
вызывать всякий раз, когда в куче уже есть карта, и игрок блокирует take()
звонить всякий раз, когда куча была пуста.
Вы могли бы поставить sleep()
вызывает в любом цикле, чтобы имитировать дилера и игрока время.
Что касается разницы между sleep()
а также wait()
;
Вы можете достичь того же эффекта, что и sleept(t)
позвонив foo.wait(t)
на объекте foo
это никогда не получит уведомления. Итак, технически, sleep()
Излишне: мы все могли бы обойтись без этого.
Но имена важны. Когда я вижу foo.wait()
в программе я ожидаю, что вызывающая сторона ожидает какого-то другого потока, чтобы сделать что-то, связанное с foo
объект, и когда я вижу sleep()
Я знаю, что звонящий просто убивает время.