Ждать и уведомлять методы в синхронизации?

Так что мой проект - симуляция карточного типа. У меня есть класс Дилер, Игрок и Куча. Куча - это общий ресурс, где дилер кладет одну (не множественную, а только одну) карту, и игрок забирает ее. Я создаю две темы, одну для дилера и одну для игрока. Предполагается, что дилер подождет, пока ему не сообщат, что игрок забрал карту; Затем он приступит к установке новой карты вниз. Точно так же Игрок будет ждать, пока не получит уведомление о том, что дилер положил карту вниз, а затем Игрок заберет карту.

Предполагается также механизм, который игрок и дилер будут использовать для подтверждения того, что им разрешено положить или взять карту из кучи. Я использовал логическое значение; Если логическое значение истинно или ложно, Игроку или Дилеру может или не может быть разрешено выполнять свои соответствующие действия.

В то же время, Игрок и Дилер находятся в спящем режиме в течение произвольного интервала времени, когда они затем проснутся и проверит, могут ли они выполнить свои действия. Если они не могут, они будут ждать, пока их не уведомят.

Мой вопрос связан с методами ожидания и уведомления. В чем разница между ожиданием и сном? Как бы я поступил так, чтобы Игрок / Дилер проснулся ото сна, и они вынуждены ждать, пока их не уведомят, если им не позволено взять / добавить карту из кучи? Кроме того, я даже делаю синхронизацию должным образом?

Извините, что мой код действительно грязный. Пожалуйста, попросите разъяснений.

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() Я знаю, что звонящий просто убивает время.

Другие вопросы по тегам