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 }