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; package exercises.ex_z4;
import java.util.Random; import java.util.Arrays;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
public class AuctionMain { public class AuctionMain {
public static final String[] names = { public static final String[] names = {
"Sabrina", "José", "Patrick", "Salomé", "Lisa", "Alfred", "Annna", "Alex", "Kevin" "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) { public static void main(String[] args) {
Semaphore mutex = new Semaphore(1); Auctioneer auctioneer = new Auctioneer("Paul", Arrays.asList(items));
ConcurrentLinkedQueue<Bid> bids = new ConcurrentLinkedQueue<>();
Auctioneer auctioneer = new Auctioneer("Paul", bids, mutex);
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])).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; package exercises.ex_z4;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.Semaphore;
import static exercises.ex_z4.AuctionState.*;
public class Auctioneer implements Runnable { public class Auctioneer implements Runnable {
private String name; private String name;
private ConcurrentLinkedQueue<Bid> bids; private Queue<Bid> bids = new ConcurrentLinkedQueue<>();
private Semaphore mutex;
private Bid maximumBid; private Bid maximumBid;
private Thread countdownThread = null; 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.name = name;
this.bids = bids; this.items = items;
this.mutex = mutex; }
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) { public void placeBid(Bid bid) {
bids.add(bid); if (auctionState == BIDDING) {
System.out.println(bid.bidder() + " bids $" + bid.amount());
bids.add(bid);
}
notify(); notify();
} }
@ -30,7 +52,7 @@ 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);
System.out.println("End of the Auction !"); auctionState = SOLD;
notify(); notify();
} catch (InterruptedException _) {} } catch (InterruptedException _) {}
} }
@ -44,38 +66,52 @@ public class Auctioneer implements Runnable {
return maximumBid; return maximumBid;
} }
public void endAuction(){ public AuctionState getAuctionState() {
System.out.println("End of the auction ! "); return auctionState;
notifyAll(); }
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 @Override
public void run() { public void run() {
while (true) { while (auctionState != FINISHED) {
try { try {
mutex.acquire(); switch (auctionState) {
Bid current_bid = bids.poll(); case PRESENTING_ITEM -> {
if (current_bid == null) { presentItem();
startCountdown();
wait();
if (bids.isEmpty()) {
endAuction();
} }
continue; case BIDDING -> {
} Bid current_bid = bids.poll();
if (!bids.isEmpty()) { if (current_bid == null) {
if (current_bid.amount() > maximumBid.amount()) { startCountdown();
maximumBid = current_bid; wait();
System.out.println("New bid : " + maximumBid.amount() + " by " + maximumBid.bidder()); } else {
mutex.release(); if (current_bid.amount() > maximumBid.amount()) {
return; maximumBid = current_bid;
announce("New best bid : " + maximumBid.amount() + " by " + maximumBid.bidder());
}
}
}
case SOLD -> {
finalizeBidding();
} }
} else {
mutex.release();
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} }
} }
announce("The auction is now finished ! Thank you for participating !");
} }
} }

View File

@ -1,30 +1,53 @@
package exercises.ex_z4; package exercises.ex_z4;
import exercises.Utils;
import java.util.Random; import java.util.Random;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import static exercises.ex_z4.AuctionState.BIDDING;
import static exercises.ex_z4.AuctionState.FINISHED;
public class Bidder implements Runnable { public class Bidder implements Runnable {
private static int nextId = 0; private static int nextId = 0;
private final String name; private final String name;
private final int id; private final int id;
private final List<Item> items = new ArrayList<>(); private final List<Item> items = new ArrayList<>();
private Double lastBid = null; private Double lastBid = null;
private final Auctioneer auctioneer;
public Bidder(String name) { public Bidder(String name, Auctioneer auctioneer) {
this.name = name; this.name = name;
this.id = nextId++; this.id = nextId++;
this.auctioneer = auctioneer;
} }
@Override @Override
public void run() { public void run() {
while(true){ while (true) {
Random rand = new Random(); AuctionState state = auctioneer.getAuctionState();
double addon = rand.nextDouble(500); if (state == BIDDING) {
lastBid += addon; Random rand = new Random();
double addon = rand.nextDouble(500);
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() { public String getName() {
return name; return name;
} }