001    
002    import java.util.concurrent.locks.Lock;
003    import java.util.concurrent.locks.ReentrantLock;
004    import java.util.concurrent.locks.Condition;
005    
006    /**
007     * Konto version C.
008     * Uses java.util.concurrent mutexes to synchronize and coordinate. 
009     * Implements methods to display, add and remove money from the account, 
010     * account cannot become negative.
011     * @author Heinz Kredel.
012     */
013    
014    public class KontoC implements Konto {
015    
016        protected double stand; // Konto Stand
017    
018        protected final Lock      mutex  = new ReentrantLock();
019        protected final Condition imPlus = mutex.newCondition();
020    
021        public KontoC() { 
022            this(0.0); 
023        }
024    
025        public KontoC(double a) { 
026            stand = a; 
027        }
028    
029    
030    /**
031     * Displays account balance.
032     * @return stand.
033     */
034        public double zeigeGeld() { 
035            mutex.lock();
036            try {
037                return stand; 
038            } finally {
039                mutex.unlock();
040            }
041        }
042    
043    
044    /**
045     * Transfers amount to this account.
046     * Blocks if account would become negative.
047     * @param b amount to put on account.
048     * @return s returns actual balance from account.
049     */
050        public double putGeld(double b) { // stand += b
051            mutex.lock();
052            try {
053                double s = stand + b;
054                WorkC.schaffen(100);
055                // nur falls s >= 0
056                while (s < 0 && stand > s) { // increasing negative allowed
057                      try { 
058                          imPlus.await();
059                      } catch(InterruptedException e) { 
060                      } 
061                      s = stand + b;
062                }
063                if (s >= 0 || s > stand) imPlus.signal();
064                stand = s;
065                return s;   
066            } finally {
067                mutex.unlock();
068            }
069        }
070    
071    
072    /**
073     * New account balance gets calculated and returned.
074     * Blocks if account would become negative.
075     * @param b amount to remove from desired account.
076     * @return s current account balance.
077     */
078        public double getGeld(double b) { // stand -= b
079            mutex.lock();
080            try {
081                double s = stand - b;
082                WorkC.schaffen(100);
083                // nur falls s >= 0
084                while (s < 0 && stand > s) { // increasing negative allowed
085                      try { 
086                          imPlus.await();       
087                      } catch(InterruptedException e) { 
088                      } 
089                      s = stand - b;
090                }
091                if (s >= 0 || s > stand) imPlus.signal();
092                stand = s;
093                return s;   
094            } finally {
095                mutex.unlock();
096            }
097        }
098    
099    }
100    
101    
102    /**
103     * Sending current thread to sleep for a random time.
104     */
105    class WorkC {
106    
107    /**
108     * @param max An Integer, defines range of numbers for Math.random().
109     */
110        public static void schaffen(int max) {
111            try {
112                Thread.currentThread().sleep( (int)(max*Math.random()) );
113            } catch (InterruptedException e) {
114                  System.out.println("Dies sollte nicht passieren "+e);
115            }
116        }
117    }