finished ex Z4

This commit is contained in:
Louis Heredero 2025-01-20 23:52:55 +01:00
parent 886bf5a1cd
commit fd3af32c7c
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7
3 changed files with 83 additions and 29 deletions

View File

@ -1,5 +1,6 @@
package exercises.ex_z4; package exercises.ex_z4;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -16,10 +17,8 @@ public class AuctionMain {
}; };
public static void main(String[] args) { public static void main(String[] args) {
Auctioneer auctioneer = new Auctioneer("Paul", Arrays.asList(items)); Auctioneer auctioneer = new Auctioneer("Paul", new ArrayList(Arrays.stream(items).toList()));
new Thread(auctioneer).start(); new Thread(auctioneer).start();
for (int i = 0; i < names.length; i++) { for (int i = 0; i < names.length; i++) {
new Thread(new Bidder(names[i], auctioneer)).start(); new Thread(new Bidder(names[i], auctioneer)).start();
} }

View File

@ -1,29 +1,48 @@
package exercises.ex_z4; package exercises.ex_z4;
import java.util.List; import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Queue; import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import static exercises.ex_z4.AuctionState.*; import static exercises.ex_z4.AuctionState.*;
public class Auctioneer implements Runnable { public class Auctioneer implements Runnable {
private String name; private static final DecimalFormat df = new DecimalFormat("#.00");
private Queue<Bid> bids = new ConcurrentLinkedQueue<>();
private final String name;
private final Queue<Bid> bids = new ConcurrentLinkedQueue<>();
private final ArrayList<Item> items;
private final Lock bidLock = new ReentrantLock();
private final Condition bidCond = bidLock.newCondition();
public final Lock stateLock = new ReentrantLock();
public final Condition stateCond = stateLock.newCondition();
private Bid maximumBid; private Bid maximumBid;
private Thread countdownThread = null; private Thread countdownThread = null;
private boolean isAuctionActive = false;
private AuctionState auctionState = PRESENTING_ITEM; private AuctionState auctionState = PRESENTING_ITEM;
private final List<Item> items;
public Auctioneer(String name, List<Item> items) { public Auctioneer(String name, ArrayList<Item> items) {
this.name = name; this.name = name;
this.items = items; this.items = items;
} }
private void announce(String msg) { private void announce(String msg) {
System.out.println("[Auctioneer] " + msg); System.out.println("[Auctioneer " + name + "] " + msg);
}
private void setState(AuctionState newState) {
stateLock.lock();
try {
auctionState = newState;
stateCond.signalAll();
} finally {
stateLock.unlock();
}
} }
public void presentItem() throws InterruptedException { public void presentItem() throws InterruptedException {
@ -32,15 +51,21 @@ public class Auctioneer implements Runnable {
announce("Get ready to bid..."); announce("Get ready to bid...");
Thread.sleep(2000); Thread.sleep(2000);
announce("Bidding open !"); announce("Bidding open !");
auctionState = BIDDING; maximumBid = null;
setState(BIDDING);
} }
public void placeBid(Bid bid) { public void placeBid(Bid bid) {
if (auctionState == BIDDING) { if (auctionState == BIDDING) {
System.out.println(bid.bidder() + " bids $" + bid.amount()); System.out.println(bid.bidder() + " bids $" + df.format(bid.amount()));
bidLock.lock();
try {
bids.add(bid); bids.add(bid);
bidCond.signalAll();
} finally {
bidLock.unlock();
}
} }
notify();
} }
private void countdown() { private void countdown() {
@ -52,8 +77,13 @@ public class Auctioneer implements Runnable {
Thread.sleep(1000); Thread.sleep(1000);
System.out.println("One"); System.out.println("One");
Thread.sleep(1000); Thread.sleep(1000);
auctionState = SOLD; setState(SOLD);
notify(); bidLock.lock();
try {
bidCond.signalAll();
} finally {
bidLock.unlock();
}
} catch (InterruptedException _) {} } catch (InterruptedException _) {}
} }
@ -71,15 +101,19 @@ public class Auctioneer implements Runnable {
} }
public void finalizeBidding() throws InterruptedException { public void finalizeBidding() throws InterruptedException {
announce("And sold for $" + maximumBid.amount() + " !"); if (maximumBid == null) {
announce("Nobody wants this items ?!");
} else {
announce("And sold for $" + df.format(maximumBid.amount()) + " !");
Item item = items.removeFirst(); Item item = items.removeFirst();
announce(maximumBid.bidder() + " is now the proud owner of " + item); announce(maximumBid.bidder() + " is now the proud owner of " + item);
maximumBid.bidder().addItem(item); maximumBid.bidder().addItem(item);
}
Thread.sleep(2000); Thread.sleep(2000);
if (items.isEmpty()) { if (items.isEmpty()) {
auctionState = FINISHED; setState(FINISHED);
} else { } else {
auctionState = PRESENTING_ITEM; setState(PRESENTING_ITEM);
} }
} }
@ -94,12 +128,22 @@ public class Auctioneer implements Runnable {
case BIDDING -> { case BIDDING -> {
Bid current_bid = bids.poll(); Bid current_bid = bids.poll();
if (current_bid == null) { if (current_bid == null) {
if (maximumBid != null) {
startCountdown(); startCountdown();
wait(); }
bidLock.lock();
try {
bidCond.await();
} finally {
bidLock.unlock();
}
if (countdownThread != null) {
countdownThread.interrupt();
}
} else { } else {
if (current_bid.amount() > maximumBid.amount()) { if (maximumBid == null || current_bid.amount() > maximumBid.amount()) {
maximumBid = current_bid; maximumBid = current_bid;
announce("New best bid : " + maximumBid.amount() + " by " + maximumBid.bidder()); announce("New best bid : " + df.format(maximumBid.amount()) + " by " + maximumBid.bidder());
} }
} }
} }

View File

@ -30,16 +30,27 @@ public class Bidder implements Runnable {
if (state == BIDDING) { if (state == BIDDING) {
Random rand = new Random(); Random rand = new Random();
double addon = rand.nextDouble(500); double addon = rand.nextDouble(500);
double base = auctioneer.getMaximumBid().amount(); Bid maximumBid = auctioneer.getMaximumBid();
double base = maximumBid == null ? 0 : maximumBid.amount();
lastBid = base + addon; lastBid = base + addon;
auctioneer.placeBid(new Bid(this, lastBid)); auctioneer.placeBid(new Bid(this, lastBid));
long minSleep = (long) (base * 10);
try { try {
Utils.randomSleep(100, 5000); Utils.randomSleep(minSleep, minSleep + 1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} else if (state == FINISHED) { } else if (state == FINISHED) {
break; break;
} else {
auctioneer.stateLock.lock();
try {
auctioneer.stateCond.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
auctioneer.stateLock.unlock();
}
} }
} }
} }