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;
import java.util.ArrayList;
import java.util.Arrays;
@ -16,10 +17,8 @@ public class AuctionMain {
};
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();
for (int i = 0; i < names.length; i++) {
new Thread(new Bidder(names[i], auctioneer)).start();
}

View File

@ -1,29 +1,48 @@
package exercises.ex_z4;
import java.util.List;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Queue;
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.*;
public class Auctioneer implements Runnable {
private String name;
private Queue<Bid> bids = new ConcurrentLinkedQueue<>();
private static final DecimalFormat df = new DecimalFormat("#.00");
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 Thread countdownThread = null;
private boolean isAuctionActive = false;
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.items = items;
}
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 {
@ -32,15 +51,21 @@ public class Auctioneer implements Runnable {
announce("Get ready to bid...");
Thread.sleep(2000);
announce("Bidding open !");
auctionState = BIDDING;
maximumBid = null;
setState(BIDDING);
}
public void placeBid(Bid bid) {
if (auctionState == BIDDING) {
System.out.println(bid.bidder() + " bids $" + bid.amount());
bids.add(bid);
System.out.println(bid.bidder() + " bids $" + df.format(bid.amount()));
bidLock.lock();
try {
bids.add(bid);
bidCond.signalAll();
} finally {
bidLock.unlock();
}
}
notify();
}
private void countdown() {
@ -52,8 +77,13 @@ public class Auctioneer implements Runnable {
Thread.sleep(1000);
System.out.println("One");
Thread.sleep(1000);
auctionState = SOLD;
notify();
setState(SOLD);
bidLock.lock();
try {
bidCond.signalAll();
} finally {
bidLock.unlock();
}
} catch (InterruptedException _) {}
}
@ -71,15 +101,19 @@ public class Auctioneer implements Runnable {
}
public void finalizeBidding() throws InterruptedException {
announce("And sold for $" + maximumBid.amount() + " !");
Item item = items.removeFirst();
announce(maximumBid.bidder() + " is now the proud owner of " + item);
maximumBid.bidder().addItem(item);
if (maximumBid == null) {
announce("Nobody wants this items ?!");
} else {
announce("And sold for $" + df.format(maximumBid.amount()) + " !");
Item item = items.removeFirst();
announce(maximumBid.bidder() + " is now the proud owner of " + item);
maximumBid.bidder().addItem(item);
}
Thread.sleep(2000);
if (items.isEmpty()) {
auctionState = FINISHED;
setState(FINISHED);
} else {
auctionState = PRESENTING_ITEM;
setState(PRESENTING_ITEM);
}
}
@ -94,12 +128,22 @@ public class Auctioneer implements Runnable {
case BIDDING -> {
Bid current_bid = bids.poll();
if (current_bid == null) {
startCountdown();
wait();
if (maximumBid != null) {
startCountdown();
}
bidLock.lock();
try {
bidCond.await();
} finally {
bidLock.unlock();
}
if (countdownThread != null) {
countdownThread.interrupt();
}
} else {
if (current_bid.amount() > maximumBid.amount()) {
if (maximumBid == null || current_bid.amount() > maximumBid.amount()) {
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) {
Random rand = new Random();
double addon = rand.nextDouble(500);
double base = auctioneer.getMaximumBid().amount();
Bid maximumBid = auctioneer.getMaximumBid();
double base = maximumBid == null ? 0 : maximumBid.amount();
lastBid = base + addon;
auctioneer.placeBid(new Bid(this, lastBid));
long minSleep = (long) (base * 10);
try {
Utils.randomSleep(100, 5000);
Utils.randomSleep(minSleep, minSleep + 1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else if (state == FINISHED) {
break;
} else {
auctioneer.stateLock.lock();
try {
auctioneer.stateCond.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} finally {
auctioneer.stateLock.unlock();
}
}
}
}