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 }