progress on ex Z4

This commit is contained in:
Louis Heredero 2025-01-13 20:47:24 +01:00
parent afc2fbfa8a
commit 886bf5a1cd
Signed by: HEL
GPG Key ID: 8D83DE470F8544E7
4 changed files with 112 additions and 41 deletions

View File

@ -1,23 +1,27 @@
package exercises.ex_z4;
import java.util.Random;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import java.util.Arrays;
public class AuctionMain {
public static final String[] names = {
"Sabrina", "José", "Patrick", "Salomé", "Lisa", "Alfred", "Annna", "Alex", "Kevin"
};
public static final Item[] items = {
new Item("Album de Sabrina Carpenter"),
new Item("Chaussette gauche de Freddie Mercury"),
new Item("Peigne de Michael Jackson"),
new Item("Décapsuleur de Kurt Cobain")
};
public static void main(String[] args) {
Semaphore mutex = new Semaphore(1);
ConcurrentLinkedQueue<Bid> bids = new ConcurrentLinkedQueue<>();
Auctioneer auctioneer = new Auctioneer("Paul", bids, mutex);
Auctioneer auctioneer = new Auctioneer("Paul", Arrays.asList(items));
new Thread(auctioneer).start();
for (int i = 0; i < names.length; i++) {
new Thread(new Bidder(names[i])).start();
new Thread(new Bidder(names[i], auctioneer)).start();
}
}
}

View File

@ -0,0 +1,8 @@
package exercises.ex_z4;
public enum AuctionState {
PRESENTING_ITEM,
BIDDING,
SOLD,
FINISHED
}

View File

@ -1,23 +1,45 @@
package exercises.ex_z4;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import static exercises.ex_z4.AuctionState.*;
public class Auctioneer implements Runnable {
private String name;
private ConcurrentLinkedQueue<Bid> bids;
private Semaphore mutex;
private Queue<Bid> bids = new ConcurrentLinkedQueue<>();
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, ConcurrentLinkedQueue<Bid> bids, Semaphore mutex) {
public Auctioneer(String name, List<Item> items) {
this.name = name;
this.bids = bids;
this.mutex = mutex;
this.items = items;
}
private void announce(String msg) {
System.out.println("[Auctioneer] " + msg);
}
public void presentItem() throws InterruptedException {
Item item = items.getFirst();
announce("Now selling this new item: '" + item.name() + "'");
announce("Get ready to bid...");
Thread.sleep(2000);
announce("Bidding open !");
auctionState = BIDDING;
}
public void placeBid(Bid bid) {
if (auctionState == BIDDING) {
System.out.println(bid.bidder() + " bids $" + bid.amount());
bids.add(bid);
}
notify();
}
@ -30,7 +52,7 @@ public class Auctioneer implements Runnable {
Thread.sleep(1000);
System.out.println("One");
Thread.sleep(1000);
System.out.println("End of the Auction !");
auctionState = SOLD;
notify();
} catch (InterruptedException _) {}
}
@ -44,38 +66,52 @@ public class Auctioneer implements Runnable {
return maximumBid;
}
public void endAuction(){
System.out.println("End of the auction ! ");
notifyAll();
public AuctionState getAuctionState() {
return auctionState;
}
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);
Thread.sleep(2000);
if (items.isEmpty()) {
auctionState = FINISHED;
} else {
auctionState = PRESENTING_ITEM;
}
}
@Override
public void run() {
while (true) {
while (auctionState != FINISHED) {
try {
mutex.acquire();
switch (auctionState) {
case PRESENTING_ITEM -> {
presentItem();
}
case BIDDING -> {
Bid current_bid = bids.poll();
if (current_bid == null) {
startCountdown();
wait();
if (bids.isEmpty()) {
endAuction();
}
continue;
}
if (!bids.isEmpty()) {
} else {
if (current_bid.amount() > maximumBid.amount()) {
maximumBid = current_bid;
System.out.println("New bid : " + maximumBid.amount() + " by " + maximumBid.bidder());
mutex.release();
return;
announce("New best bid : " + maximumBid.amount() + " by " + maximumBid.bidder());
}
} else {
mutex.release();
}
}
case SOLD -> {
finalizeBidding();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
announce("The auction is now finished ! Thank you for participating !");
}
}

View File

@ -1,28 +1,51 @@
package exercises.ex_z4;
import exercises.Utils;
import java.util.Random;
import java.util.ArrayList;
import java.util.List;
import static exercises.ex_z4.AuctionState.BIDDING;
import static exercises.ex_z4.AuctionState.FINISHED;
public class Bidder implements Runnable {
private static int nextId = 0;
private final String name;
private final int id;
private final List<Item> items = new ArrayList<>();
private Double lastBid = null;
private final Auctioneer auctioneer;
public Bidder(String name) {
public Bidder(String name, Auctioneer auctioneer) {
this.name = name;
this.id = nextId++;
this.auctioneer = auctioneer;
}
@Override
public void run() {
while (true) {
AuctionState state = auctioneer.getAuctionState();
if (state == BIDDING) {
Random rand = new Random();
double addon = rand.nextDouble(500);
lastBid += addon;
double base = auctioneer.getMaximumBid().amount();
lastBid = base + addon;
auctioneer.placeBid(new Bid(this, lastBid));
try {
Utils.randomSleep(100, 5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
} else if (state == FINISHED) {
break;
}
}
}
public void addItem(Item item){
items.add(item);
}
public String getName() {