如何使用Java多线程来模拟汽车在停车场的随机进出?

kmpatx3s  于 2022-12-25  发布在  Java
关注(0)|答案(1)|浏览(204)

所以我一直在做一些Java多线程项目来更好地理解这个问题。我写了一些代码来解决一个停车场问题。基本上,线程形式的多辆汽车应该随机进入和退出一组停车位。我想我还没有完全理解Java同步的概念。
下面是我的代码:

public class CarPark
{
 
    private int slots;

    public CarPark(int slots) 
    { 
        if(slots < 0)
            slots = 0;
        this.slots = slots; 
    } 

    // Try to enter the car park
    public void tryParking(String car)
    {
        
        if (slots >= 1) // At least one free slot to park in the car park
        {
            park(car);  
        }
        else if (slots <= 0) // If there is no free slot then the car has to wait
        {
            System.out.println(car + ": is waiting for a slot. Free slots: " + slots);
        }

    }
    
    // Parking in the car park
    private void park(String car)
    { 
        slots--;
        System.out.println(car + ": is parking. Free slots: " + slots);
    } 

    // Leaving the car park
    public void leave(String car) 
    { 
        slots++;
        System.out.println(car + ": is leaving the car park. Free slots: " + slots);
    }

    public static void main( String[] args)
    {
        // 5 slots
        CarPark carpark = new CarPark(5);

        // 20 Cars
        for (int i=1; i<=20; i++) {
            Car a = new Car("Car " + i, carpark);
        }
    }
}

class Car extends Thread 
{ 
    private CarPark carpark; 

    public Car(String name, CarPark carpark) 
    { 
        super(name); 
        this.carpark = carpark;
        start(); 
    } 

    public void run() 
    {
        try {
            sleep((int)(Math.random() * 1000)); 
        } catch( InterruptedException e) { }
        
        carpark.tryParking(getName()); 
        
        try {
            sleep((int)(Math.random() * 2000)); 
        }
        catch( InterruptedException e) { } 
        
        carpark.leave(getName());
    } 
}

所以现在我面临的问题是,汽车正在退出插槽(并"生产"免费插槽),从来没有停在那里摆在首位。我如何让汽车只退出,如果他们停在停车场第一?

xriantvc

xriantvc1#

所以现在我面临的问题是,汽车正在退出插槽(并“生产”免费插槽),从来没有停在那里摆在首位。我如何让汽车只退出,如果他们停在停车场第一?
有很多种方法可以做到这一点,你有一个Car对象,你可以用布尔字段记录汽车停过了,或者你可以只返回true或false,如果tryParking()能够停汽车的话。
这就回答了你的问题,但是你的代码中确实没有同步。你不能因为使用Thread就免费获得同步。如果你真的想同步数据和保护关键代码段,你需要使用synchronizedvolatile,或者其他锁定或线程安全类。
下面是代码中的一些具体问题:

  • 这里需要一些同步。当线程在不同的CPU上运行时,它们都阅读更新Carpark.slots字段。这是争用条件的定义。两个线程可以同时将插槽从0更新为1,将值保留为1而不是2。我会将其改为AtomicInteger
  • 正如在评论中指出的,tryParking()并不是在等待一个空格。如果你需要等待,那么你需要使用一个synchronized (this),然后调用this.wait()this.notify()。正确地做到这一点并不容易,但是有很多tutorials on the subject
  • 线程不应该在构造函数中使用start(),因为构造函数会重新排序,并且this会“转义”到另一个线程。调用方应该在Car构造函数返回后调用car.start()。请参见this explanation
  • 实现Runnable而不是扩展Thread和做new Thread(new Car())类型模型是更好的模式。
  • 注意吸收InterruptedException。调用Thread.currentThread().interrupt()是确保传播中断状态的更好模式。

相关问题