class NegativeException extends Exception{
    NegativeException(double value){
	super("Negative value " + value + " not allowed.");
    }
}

class CreditCard{
    int credit = 60000;

    public int getcredit(){ return credit; }
    public synchronized void spend(int amount) throws NegativeException{
        int newcredit = credit - amount;
        credit = newcredit;
        
        if (credit < 0)
            throw new NegativeException(credit);
    }
}

class Person extends Thread{
    int tospend;
    CreditCard c;
    Person(int tospend, CreditCard c){ this.tospend = tospend; this.c = c;}
    void spend() throws NegativeException, InterruptedException{
	synchronized(c){
	    int credit = c.getcredit();
	    Thread.sleep(100);
	    if (credit >= tospend){
		c.spend(tospend);
	    }
	}
    }

    synchronized void spend_wrong() throws NegativeException, InterruptedException{
	    int credit = c.getcredit();
	    Thread.sleep(100);
	    if (credit >= tospend){
		c.spend(tospend);
	    }
    }

    void spend_wrong_equiv() throws NegativeException, InterruptedException{
	synchronized(this){
	    int credit = c.getcredit();
	    Thread.sleep(100);
	    if (credit >= tospend){
		c.spend(tospend);
	    }
	}
    }

    public void run(){
        try{
            spend();
        }
        catch(Exception e){
            System.out.println(e);
        }
    }
}

public class CreditCardDemo{
    public static void main(String[] argv){
        for(int i = 0; i < Integer.parseInt(argv[0]); i++){
            CreditCard c = new CreditCard();
            Person George = new Person(50000, c);
            Person Mary = new Person(20000, c);
            
            George.start();
            Mary.start();
        }
    }
}
        

