繁体   English   中英

等待并通知同步中的方法?

[英]Wait and Notify Methods in Synchronization?

所以我的项目是卡片类型模拟。 我有一个Dealer,Player和Heap类。 堆是一种共享资源,发牌人将一张(不是多张,只有一张)放置在纸牌上,然后玩家将其拿起。 我创建了两个线程,一个用于经销商,一个用于玩家。 发牌人应该等到通知他玩家已经拿起卡为止。 然后他将继续放下新卡。 同样,玩家将一直等到收到发牌人放下纸牌的通知后,再将纸牌拿起。

还应该有一种机制,玩家和发牌者都将使用这种机制来确认允许他们从堆中放置或取出卡片。 我用了一个布尔值; 如果布尔值为true或false,则将允许或不允许玩家或交易者执行其相应的操作。

同时,玩家和庄家被设置为随机睡眠一段时间,然后他们将醒来并检查他们是否可以执行其动作。 如果不能,他们将等到收到通知。

我的问题涉及等待和通知方法。 等待和睡眠有什么区别? 我该如何使玩家/经销商从睡眠中醒来,如果不允许他们从堆中取出/添加卡,他们将被迫等待直到被通知为止? 另外,我什至没有正确进行同步?

对不起,我的代码真的很乱。 请要求澄清。

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"

}

解决您的问题的一种方法是使Heap成为一个固定容量为一个元素的ArrayBlockingQueue。 Dealer只会循环put()婷卡到堆,而Player将环, take() ING卡从堆中。

每当堆中已经有一张牌时,发牌者就会自动阻止(即等待) put()调用,而只要堆为空,发牌者就会自动阻止take()调用。

您可以将sleep()调用放入任一循环中,以模拟经销商和玩家花费的时间。


关于sleep()wait()之间的区别;

通过对永不通知的对象foo调用foo.wait(t) ,可以实现与sleept(t)完全相同的效果。 因此,从技术上讲sleep()是多余的:没有它,我们都可以相处。

但是名字很重要。 当我在程序中看到foo.wait()时,我期望调用foo.wait()在等待其他线程执行与foo对象相关的操作,并且当我看到sleep()我知道调用foo.wait()在消磨时间。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM