Compare commits

..

4 Commits

Author SHA1 Message Date
b5540fc68d added README 2025-01-21 00:26:26 +01:00
fd3af32c7c finished ex Z4 2025-01-20 23:52:55 +01:00
886bf5a1cd progress on ex Z4 2025-01-13 20:47:24 +01:00
afc2fbfa8a started ex Z4 2025-01-13 18:18:14 +01:00
15 changed files with 683 additions and 0 deletions

124
.idea/uiDesigner.xml generated Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Palette2">
<group name="Swing">
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
</item>
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
</item>
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.svg" removable="false" auto-create-binding="false" can-attach-label="true">
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
</item>
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
<initial-values>
<property name="text" value="Button" />
</initial-values>
</item>
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="RadioButton" />
</initial-values>
</item>
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
<initial-values>
<property name="text" value="CheckBox" />
</initial-values>
</item>
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
<initial-values>
<property name="text" value="Label" />
</initial-values>
</item>
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
<preferred-size width="150" height="-1" />
</default-constraints>
</item>
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
</item>
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
<preferred-size width="150" height="50" />
</default-constraints>
</item>
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
<preferred-size width="200" height="200" />
</default-constraints>
</item>
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.svg" removable="false" auto-create-binding="true" can-attach-label="true">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
</item>
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
</item>
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
</item>
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
<preferred-size width="-1" height="20" />
</default-constraints>
</item>
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.svg" removable="false" auto-create-binding="false" can-attach-label="false">
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
</item>
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.svg" removable="false" auto-create-binding="true" can-attach-label="false">
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
</item>
</group>
</component>
</project>

80
README.md Normal file
View File

@@ -0,0 +1,80 @@
# Concurrent Programming
This repository holds all my answers to the exercises for the 202.2 Concurrent Programming course
> [!NOTE]
> Some exercises may not be complete, although most of them are fully functioning
## Table of Contents
* [Exercises](#exercises)
* [Lab 01 - Thread Objects and Synchronization](#lab-01---thread-objects-and-synchronization)
* [Lab 01 (bis) - Thread Objects and Synchronization](#lab-01-bis---thread-objects-and-synchronization)
* [Lab 02 - Liveness, Guarded Blocks and Immutable Objects](#lab-02---liveness-guarded-blocks-and-immutable-objects)
* [Lab 02 (bis) - Liveness, Guarded Blocks and Immutable Objects](#lab-02-bis---liveness-guarded-blocks-and-immutable-objects)
* [Lab 03 - Lock Objects](#lab-03---lock-objects)
* [Lab 03 (bis) - Lock Objects](#lab-03-bis---lock-objects)
* [Lab 04 - Executors, Callable and Fork-Join](#lab-04---executors-callable-and-fork-join)
* [Lab 05 - Concurrent Collections and Atomic Variables](#lab-05---concurrent-collections-and-atomic-variables)
* [Lab 06 - Synchronizers](#lab-06---synchronizers)
* [Lab 07 (Workshop) - Summarizing exercises](#lab-07-workshop---summarizing-exercises)
## Exercises
### Lab 01 - Thread Objects and Synchronization
- [A: Defining and Starting A Thread](src/exercises/ex_a/TestingSimpleThreads.java)
- [B: Pausing Execution With Sleep](src/exercises/ex_b/TestingSleep.java)
- [C: Interruptions](src/exercises/ex_c/TestingSleep.java)
- [D: Joins](src/exercises/ex_d/TestingJoins.java)
- [E: Thread Interference: Managing Bank Accounts](src/exercises/ex_e/TestingThreadInterferences.java)
- [F: Synchronized Methods: Ensuring consistent operations on bank accounts](src/exercises/ex_f/TestingThreadInterferences.java)
- [G: Synchronized Statements](src/exercises/ex_g/TestingSynchronizedStatements.java)
### Lab 01 (bis) - Thread Objects and Synchronization
- [Dbis: Joins](src/exercises/ex_d_bis/TestStepThreads.java)
### Lab 02 - Liveness, Guarded Blocks and Immutable Objects
- [H1: Refactoring from Deadlocks](src/exercises/ex_h1/TestThreadWithDeadlock.java)
- [H2: Bridge crossing without deadlock](src/exercises/ex_h2/TestDeadlockBridge.java)
- [I: Starvation: simulating the access of employees to a conference room](src/exercises/ex_i/TestingStarvation.java)
- [J: Livelock : couple eating](src/exercises/ex_j/LivelockDinner.java)
- [K: Guarded Blocks : managing packages in a post office](src/exercises/ex_k/TestingGuardedBlocks.java)
- ~~L: Immutable objects: From person to statue~~
### Lab 02 (bis) - Liveness, Guarded Blocks and Immutable Objects
- [Kbis1: Guarded Blocks : a service desk](src/exercises/ex_k_bis1/TestServiceDesk.java)
- ~~Kbis2: Playing Tennis~~
### Lab 03 - Lock Objects
- ~~M: ReentrantLock: Sharing a Vehicle in a couple~~
- [N: ReentrantReadWriteLock: News Feed](src/exercises/ex_n/TestingReentrantReadWriteLock_News.java)
- [O: ReentrantLockWithConditions: NumberProducersConsumers](src/exercises/ex_o/TestingReentrantLockWithConditions.java)
### Lab 03 (bis) - Lock Objects
- [Nbis: ReentrantReadWriteLock: Managing a library catalog system](src/exercises/ex_n_bis/LibraryCatalog.java)
### Lab 04 - Executors, Callable and Fork-Join
- [P: Executors for Drums](src/exercises/ex_p/Partition.java)
- [Pbis: Christmas Lights Task Scheduler](src/exercises/ex_p_bis/ChristmasTreeTester.java)
- [Q1: Callables and Futures for a Pizzeria](src/exercises/ex_q1/Pizzeria.java)
- [Q2: Fork/Join: Song](src/exercises/ex_q2/ForkJoinTest.java)
- [Q3: Arrays.parallelSort](src/exercises/ex_q3/Library.java)
- ~~Q4: Concurrent Array Sum Calculation~~
### Lab 05 - Concurrent Collections and Atomic Variables
- [R: BlockingQueue: Simulating a PostOffice](src/exercises/ex_r/TestingBlockingQueue_PostOffice.java)
- [S1: ConcurrentHashMap in the Farm](src/exercises/ex_s1/TestingConcurrentHashMap_Farm.java)
- [S2: Comparing Atomic Arrays and Standard Arrays](src/exercises/ex_s2/TestingAtomicInteger.java)
- [S3: java.util.concurrent.atomic package: Creativity](src/exercises/ex_s3/TestingAtomicLong.java)
### Lab 06 - Synchronizers
- [T: Semaphore for Dog Feeding](src/exercises/ex_t/TestingSemaphore_DogBreeder.java)
- [U: CountDownLatch: Starting the Family Trip](src/exercises/ex_u/TestingCountDownLatch_FamilyTrip.java)
- [V: CyclicBarrier: Patrouille de Glaciers](src/exercises/ex_v/TestingCyclicBarrier_PDG.java)
- [W: Exchanger: Bring my Car to the Garage](src/exercises/ex_w/TestingExchanger_Garage.java)
- [X: Phaser for the Next Family Bike Trip](src/exercises/ex_x/TestingPhaserFamilyBikeTrip.java)
- [y: Synchronized Race (former exam)](src/exercises/ex_y/RaceTester.java)
### Lab 07 (Workshop) - Summarizing exercises
- ~~Z1: The dining philosophers~~
- ~~Z2: The Sleeping Barber Problem~~
- ~~Z3: Print Queue Management~~
- [Z4: Concurrent Auction Problem](src/exercises/ex_z4/AuctionMain.java)

View File

@@ -0,0 +1,17 @@
package exercises.ex_k_bis1;
public class Customer implements Runnable {
/*private String name;
private ServiceDesk serviceDesk;
public Customer(String name, ServiceDesk serviceDesk) {
this.name = name;
this.serviceDesk = serviceDesk;
}
*/
@Override
public void run() {
}
}

View File

@@ -0,0 +1,22 @@
package exercises.ex_k_bis1;
public class TestServiceDesk {
public static void main(String[] args) {
/*
ServiceDesk serviceDesk = new ServiceDesk(2);
for (int j = 0; j<3; j++) {
new Thread(new ServiceRepresentative(serviceDesk), "Employee-"+ j).start();
}
// Start customer threads
for (int i = 0; i < 10; i++) { // 30 customers
String name = "Customer-" + i;
new Thread(new Customer(name, serviceDesk)).start();
try {
Thread.sleep((int) (Math.random() * 1000)); // Random arrival
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
*/
}
}

View File

@@ -0,0 +1,75 @@
package exercises.ex_n_bis;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class LibraryCatalog {
private final Map<String, String> catalog = new HashMap<>();
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
private final Lock readLock = lock.readLock();
private final Lock writeLock = lock.writeLock();
public LibraryCatalog() {
}
public ArrayList<Book> getBooks() {
ArrayList<Book> books = new ArrayList<>();
try {
readLock.lock();
catalog.forEach((title, author) -> {
books.add(new Book(title, author));
});
} finally {
readLock.unlock();
}
return books;
}
public String findBook(String title) {
String author;
try {
readLock.lock();
author = catalog.get(title);
} finally {
readLock.unlock();
}
if (author == null) {
System.out.println("The book '" + title + "' is not in the catalog");
return null;
}
return author;
}
public void addBook(String title, String author) {
try {
writeLock.lock();
catalog.put(title, author);
} finally {
writeLock.unlock();
}
}
public void removeBook(String title) {
try {
writeLock.lock();
catalog.remove(title);
} finally {
writeLock.unlock();
}
}
public void updateBook(String title, String newAuthor) {
try {
writeLock.lock();
catalog.replace(title, newAuthor);
} finally {
writeLock.unlock();
}
}
public record Book(String title, String author) {}
}

View File

@@ -0,0 +1,19 @@
package exercises.ex_w;
public class Car {
private String name;
private String licensePlateNumber;
public Car(String name, String licensePlateNumber) {
this.name = name;
this.licensePlateNumber = licensePlateNumber;
}
public String getLicensePlateNumber() {
return licensePlateNumber;
}
@Override
public String toString() {
return name;
}
}

View File

@@ -0,0 +1,18 @@
package exercises.ex_w;
public class Customer implements Runnable {
private final String name;
private final String licensePlateNumber;
private Car car;
public Customer(String name, Car car) {
this.name = name;
this.car = car;
licensePlateNumber = car.getLicensePlateNumber();
}
@Override
public void run() {
}
}

View File

@@ -0,0 +1,33 @@
package exercises.ex_w;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Exchanger;
public class Garage implements Runnable {
private List<Car> courtesyCars = new ArrayList<>();
private Exchanger<Car> receiveExchanger = new Exchanger<>();
public Garage() {
}
public Car leaveForRepair(Car car) throws InterruptedException {
return receiveExchanger.exchange(car);
}
@Override
public void run() {
while (true) {
Car courtesyCar = courtesyCars.removeFirst();
try {
Car toRepair = receiveExchanger.exchange(courtesyCar);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}

View File

@@ -0,0 +1,12 @@
package exercises.ex_w;
public class TestingExchanger_Garage {
String[] carTypes = {"Seat Alhambra", "BMW Mini", "Tesla 3"};
public static void main(String[] args) {
// Create a Customer thread and a Garage thread
// that use an exchanger for replacing the customer car
// with a courtesy car during the reparation. At the end of the day,
// the cars are exchanged back.
Garage garage = new Garage();
}
}

View File

@@ -0,0 +1,26 @@
package exercises.ex_z4;
import java.util.ArrayList;
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) {
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

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

View File

@@ -0,0 +1,161 @@
package exercises.ex_z4;
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 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 AuctionState auctionState = PRESENTING_ITEM;
public Auctioneer(String name, ArrayList<Item> items) {
this.name = name;
this.items = items;
}
private void announce(String 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 {
Item item = items.getFirst();
announce("Now selling this new item: '" + item.name() + "'");
announce("Get ready to bid...");
Thread.sleep(2000);
announce("Bidding open !");
maximumBid = null;
setState(BIDDING);
}
public void placeBid(Bid bid) {
if (auctionState == BIDDING) {
System.out.println(bid.bidder() + " bids $" + df.format(bid.amount()));
bidLock.lock();
try {
bids.add(bid);
bidCond.signalAll();
} finally {
bidLock.unlock();
}
}
}
private void countdown() {
try {
Thread.sleep(1000);
System.out.println("Three");
Thread.sleep(1000);
System.out.println("Two");
Thread.sleep(1000);
System.out.println("One");
Thread.sleep(1000);
setState(SOLD);
bidLock.lock();
try {
bidCond.signalAll();
} finally {
bidLock.unlock();
}
} catch (InterruptedException _) {}
}
public void startCountdown() {
countdownThread = new Thread(this::countdown);
countdownThread.start();
}
public Bid getMaximumBid() {
return maximumBid;
}
public AuctionState getAuctionState() {
return auctionState;
}
public void finalizeBidding() throws InterruptedException {
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()) {
setState(FINISHED);
} else {
setState(PRESENTING_ITEM);
}
}
@Override
public void run() {
while (auctionState != FINISHED) {
try {
switch (auctionState) {
case PRESENTING_ITEM -> {
presentItem();
}
case BIDDING -> {
Bid current_bid = bids.poll();
if (current_bid == null) {
if (maximumBid != null) {
startCountdown();
}
bidLock.lock();
try {
bidCond.await();
} finally {
bidLock.unlock();
}
if (countdownThread != null) {
countdownThread.interrupt();
}
} else {
if (maximumBid == null || current_bid.amount() > maximumBid.amount()) {
maximumBid = current_bid;
announce("New best bid : " + df.format(maximumBid.amount()) + " by " + maximumBid.bidder());
}
}
}
case SOLD -> {
finalizeBidding();
}
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
announce("The auction is now finished ! Thank you for participating !");
}
}

View File

@@ -0,0 +1,5 @@
package exercises.ex_z4;
public record Bid(Bidder bidder, double amount) {
}

View File

@@ -0,0 +1,78 @@
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, 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);
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(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();
}
}
}
}
public void addItem(Item item){
items.add(item);
}
public String getName() {
return name;
}
public int getId() {
return id;
}
public Double getLastBid() {
return lastBid;
}
@Override
public String toString() {
return "(" + id + ") " + name;
}
}

View File

@@ -0,0 +1,5 @@
package exercises.ex_z4;
public record Item(String name) {
}