Currently I have the following situation:
I Have a simplified Parking class, actually it is a monitor where clients call the lendVehicle method from other threads.
public class Parking{
private final long parkId;
private final ParkingAPI sqlLayer;
private final Lock lock = new ReentrantLock();
private final Condition notEmpty = lock.newCondition();
public Parking( long mparkId, ParkingAPI api){
sqlLayer = api;
parkId = mparkId;
}
long lendVehicle(){
lock.lock();
try{
while(sqlLayer.countVehicles(parkId) == 0)
notEmpty.await();
return sqlLayer.lend(parkId);
} finally{
lock.unlock();
}
}
void giveBackVehicle(long vehicleId){
lock.lock();
try{
sqlLayer.giveBack(vehicleId,parkId);
notEmpty.signal();
} finally{
lock.unlock();
}
}
When I mock the SQL layer with just an atomic counter, the class works perfectly, however since the application is using SQL Lite I have to protect the connection from concurrent access (basically I can execute 1 query at any given time because of SQL Lite).
Currently the code is synchronized over the DBLayer object (wich is shared across all classes).
class ParkingQuery implements ParkingAPI{
private final DBLayer connection;
public SQLLayer(DBLayer db){
connection = db;
}
@Override
int lend(long parkId){
synchronized( connection){
return connection.lendVehicleFromPark(parkId);
}
}
@Override
int countVehicles(long parkId){
synchronized( connection){
return connection.countVehiclesQuery(parkId);
}
}
@Override
void giveBack(long vehicleId, long parkId){
synchronized( connection){
connection.giveBackVehicle(parkId, vehicleId);
}
}
}
The problem is the synchronized part, wich does not play well with the Parking's monitor: wich in fact cause a deadlock.
How can I preserve functionality of parking? (Can't remove synchronized on ParkingQuery because SQLite just explode if queries are not synchronized and bad things starts happening).
Note that concurrent access to SQLLite is mandatory because that's a school project.
Aucun commentaire:
Enregistrer un commentaire