imoteb imoteb - 5 months ago 20
Java Question

Java synchronization task

I have a task to write simple booking system, I have done it except one thing, the last task I could not understand it properly, can you please give me how I can approach this last problem because I dont know even how to form a question about it and search in google:



  • Try to redesign your application so that it is still thread-safe, but without using locking mechanisms (i.e. without synchronization or
    java.util.concurrent.locks)




Here is the code I have written so far:

public class Bus{

private final boolean [] seats = new boolean[50];
private int nextSeat = 0;

public void bookSeat() throws Exception{
if(nextSeat<seats.length){
seats[nextSeat]=true;
nextSeat++;
System.out.print("Seat number " +nextSeat+ " booked");
}else{
System.out.println("The bus is full sorry");
}
}

}

public class Passenger extends Thread{

Bus bus;
String passengerName;

public Passenger(Bus bus, String passengerName){
this.bus=bus;
this.passengerName=passengerName;
}

public void run(){
synchronized(bus){
try {
bus.bookSeat();
Thread.sleep(500);
} catch (Exception ex) {
Logger.getLogger(Passenger.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("by " + passengerName);

}
}

public String getPassengerName() {
return passengerName;
}

public void setPassengerName(String passengerName) {
this.passengerName = passengerName;
}
}

public class Main {
public static void main(String [] args) throws InterruptedException{
Bus someCompany = new Bus();

Passenger p1 = new Passenger(someCompany,"Name1");
Passenger p2 = new Passenger(someCompany, "Name2");

p1.start();
p2.start();

}
}

Answer

So you need to use classes from the package java.util.concurrent.atomic, indeed they allow you to make your class thread safe without paying the price of a lock since they propose a lock free approach.

Here is how I would modify your code to make it thread safe without using intrinsic or explicit locks:

public class Bus {

    private final AtomicIntegerArray seats = new AtomicIntegerArray(50);
    private final AtomicInteger nextSeat = new AtomicInteger();

    public void bookSeat() throws Exception {
        // get the next value, then increment the sequence
        int next = nextSeat.getAndIncrement();
        // check if we don't exceed the size of the array 
        if (next < seats.length()){
            // Set the value at the index "next" to "1" for booked
            seats.set(next, 1);
            System.out.println("Seat number " +nextSeat+ " booked");
        } else {
            System.out.println("The bus is full sorry");
        }
    }
}

NB: I use an AtomicIntegerArray as there is no equivalent for boolean and we need an array with volatile values so simply 0 is false and 1 is true.