有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

多线程Java同步任务

我有一个任务要写一个简单的预订系统,我已经完成了,除了一件事,最后一个任务我不能正确理解它,你能告诉我如何解决最后一个问题吗,因为我甚至不知道如何形成一个关于它的问题并在谷歌上搜索:

  • 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)

以下是我迄今为止编写的代码:

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();

    }
}

共 (1) 个答案

  1. # 1 楼答案

    因此,您需要使用包java.util.concurrent.atomic中的类,实际上,它们允许您使类线程安全,而无需支付锁的代价,因为它们提出了一种无锁的方法

    下面是我如何修改您的代码,使其在不使用内部显式锁的情况下实现线程安全:

    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 " +next+ " booked");
            } else {
                System.out.println("The bus is full sorry");
            }
        }
    }
    

    NB:我使用AtomicIntegerArray,因为boolean没有等价物,我们 需要一个带有volatile值的数组,所以0就是false,而1就是true