Skip to content

Instantly share code, notes, and snippets.

@amuraru
Last active August 29, 2015 14:10
Show Gist options
  • Select an option

  • Save amuraru/d7fca2b1d4060b8d9322 to your computer and use it in GitHub Desktop.

Select an option

Save amuraru/d7fca2b1d4060b8d9322 to your computer and use it in GitHub Desktop.
import java.util.concurrent.locks.ReentrantReadWriteLock;
class CachedData {
Object data;
volatile boolean cacheValid;
final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
Object loadData() throws Exception {
throw new Exception("Load Failed");
}
void use(Object data) {
}
void processCachedData() {
Object data = null;
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have
// acquired write lock and changed state before we did.
if (!cacheValid) {
data = loadData();
cacheValid = true;
}
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
} catch (Exception e) {
System.out.println("load failed");
} finally {
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {
rwl.readLock().unlock();
}
}
public static void main(String[] args) {
CachedData d = new CachedData();
d.processCachedData();
}
}
// Note the rwl.readLock().lock(); moved to finally block
import java.util.concurrent.locks.ReentrantReadWriteLock;
class CachedData {
Object data;
volatile boolean cacheValid;
final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
Object loadData() throws Exception {
throw new Exception("Load Failed");
}
void use(Object data) {
}
void processCachedData() {
Object data = null;
rwl.readLock().lock();
if (!cacheValid) {
// Must release read lock before acquiring write lock
rwl.readLock().unlock();
rwl.writeLock().lock();
try {
// Recheck state because another thread might have
// acquired write lock and changed state before we did.
if (!cacheValid) {
data = loadData();
cacheValid = true;
}
} catch (Exception e) {
System.out.println("load failed");
} finally {
// Downgrade by acquiring read lock before releasing write lock
rwl.readLock().lock();
rwl.writeLock().unlock(); // Unlock write, still hold read
}
}
try {
use(data);
} finally {
rwl.readLock().unlock();
}
}
public static void main(String[] args) {
CachedData d = new CachedData();
d.processCachedData();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment