class xyz {
private Object lock = new Object();
// value will come from database
private boolean deleteOncePerDay;
private void clearAll() {
synchronized (lock) {
if(!deleteOncePerDay) {
database.deleteNames();
database.deleteAddresses();
database.deletePhoneNums();
// set database value to true
deleteOncePerDay = true;
}
}
}
@Scheduled(fixedDelay = 50000)
public void fetchNames() {
clearAll();
synchronized (lock) {
database.saveNames();
}
}
@Scheduled(fixedDelay = 50000)
public void fetchAddresses() {
clearAll();
synchronized (lock) {
database.saveAddresses();
}
}
@Scheduled(fixedDelay = 50000)
public void fetchPhoneNums() {
clearAll();
synchronized (lock) {
database.savePhoneNums();
}
}
}
3个fetch方法在不同的线程中工作,每个fetch方法需要不同的时间来保存它们的数据。
我的目标:
当一个线程正在删除(ClearAll)数据时,其他任何线程都不应同时保存数据。
当一个线程正在保存数据时,没有其他线程应该删除数据。
当没有线程在clearAll()上工作时,所有线程都可以同时保存数据。
有了以上我猜我实现了1& 2.但我错过了3.因为每个fetch方法都被synchronized块包围,所以只有fetch方法会被锁定,所以不满足条件3.
有人能帮助我吗?
答案 0 :(得分:4)
在这种情况下,您可以在java中使用ReadWriteLock。而不是synchronized(lock){}
块,使用如下。
// Initialization
ReadWriteLock lock=new ReentrantReadWriteLock();
在clearAll()
方法中。
lock.writeLock().lock();
try{
// Do your stuff here
} finally{
lock.writeLock().unlock();
}
在所有其他方法中,只需获取一个读锁定并执行您的操作。
lock.readLock().lock();
try{
// Do your stuff here
} finally{
lock.readLock().unlock();
}
ReadWriteLock允许任意数量的线程获得读锁定,但是为了获得写锁定,必须释放所有读锁定。此外,在执行写锁定时不会发生读取。
此外,我认为您应该查看数据库事务,您可以在数据库级别实现所有这些。
答案 1 :(得分:-1)
@Scheduled(fixedDelay = 50000)
public void whatever() {
clearWhatever(); // no one passed barrier, no saves happening
CyclicBarrier();
database.saveWhatever(); // all passed barrier, no clears happening.
}
根据您的1,2,3个案例,这应该将工作划分为明确并保存而不会出现并发问题。