所以我一直在做一些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());
}
}
所以现在我面临的问题是,汽车正在退出插槽(并"生产"免费插槽),从来没有停在那里摆在首位。我如何让汽车只退出,如果他们停在停车场第一?
1条答案
按热度按时间xriantvc1#
所以现在我面临的问题是,汽车正在退出插槽(并“生产”免费插槽),从来没有停在那里摆在首位。我如何让汽车只退出,如果他们停在停车场第一?
有很多种方法可以做到这一点,你有一个
Car
对象,你可以用布尔字段记录汽车停过了,或者你可以只返回true或false,如果tryParking()
能够停汽车的话。这就回答了你的问题,但是你的代码中确实没有同步。你不能因为使用
Thread
就免费获得同步。如果你真的想同步数据和保护关键代码段,你需要使用synchronized
,volatile
,或者其他锁定或线程安全类。下面是代码中的一些具体问题:
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()
是确保传播中断状态的更好模式。