@Override public Object getModuleBuilder() { return BARRIER.withRead(provideModuleInstance); }
@Override public Object invoke() { if (moduleInstance == null) BARRIER.withWrite(instantiateModule); return moduleInstance; } };
boolean readLockedAtEntry = releaseReadLock(); restoreReadLock(readLockedAtEntry);
public boolean tryIncrementCounter() { return barrier.tryWithWrite(new Runnable() { @Override public void run() { counter++; } }, 20, TimeUnit.MILLISECONDS); }
/** * Acquires the exclusive write lock before invoking the Invokable. The code will be executed exclusively, no other * reader or writer threads will exist (they will be blocked waiting for the lock). If the current thread has a read * lock, it is released before attempting to acquire the write lock, and re-acquired after the write lock is * released. Note that in that short window, between releasing the read lock and acquiring the write lock, it is * entirely possible that some other thread will sneak in and do some work, so the {@link Invokable} object should * be prepared for cases where the state has changed slightly, despite holding the read lock. This usually manifests * as race conditions where either a) some parallel unrelated bit of work has occured or b) duplicate work has * occured. The latter is only problematic if the operation is very expensive. * * @param <T> * @param invokable */ public <T> T withWrite(Invokable<T> invokable) { boolean readLockedAtEntry = releaseReadLock(); lock.writeLock().lock(); try { return invokable.invoke(); } finally { lock.writeLock().unlock(); restoreReadLock(readLockedAtEntry); } }
public boolean tryIncrementCounterHard() { return barrier.tryWithWrite(new Runnable() { @Override public void run() { counter = getCounter() + 1; } }, 20, TimeUnit.MILLISECONDS); }
@Override public Object getModuleBuilder() { return BARRIER.withRead(provideModuleInstance); }
@Override public Object invoke() { if (moduleInstance == null) BARRIER.withWrite(instantiateModule); return moduleInstance; } };
boolean readLockedAtEntry = releaseReadLock(); restoreReadLock(readLockedAtEntry);
public Boolean invoke() { if (System.currentTimeMillis() - lastCheck >= checkInterval) barrier.tryWithWrite(checker, updateTimeout, TimeUnit.MILLISECONDS); // And, now, back to code within the read lock. try { return handler.service(request, response); } catch (IOException ex) { exceptionHolder.put(ex); return false; } } };
/** * As with {@link #withRead(Invokable)}, creating an {@link Invokable} wrapper around the runnable object. */ public void withRead(final Runnable runnable) { Invokable<Void> invokable = new Invokable<Void>() { @Override public Void invoke() { runnable.run(); return null; } }; withRead(invokable); }
/** * As with {@link #withWrite(Invokable)}, creating an {@link Invokable} wrapper around the runnable object. */ public void withWrite(final Runnable runnable) { Invokable<Void> invokable = new Invokable<Void>() { @Override public Void invoke() { runnable.run(); return null; } }; withWrite(invokable); }
/** * Acquires the exclusive write lock before invoking the Invokable. The code will be executed exclusively, no other * reader or writer threads will exist (they will be blocked waiting for the lock). If the current thread has a read * lock, it is released before attempting to acquire the write lock, and re-acquired after the write lock is * released. Note that in that short window, between releasing the read lock and acquiring the write lock, it is * entirely possible that some other thread will sneak in and do some work, so the {@link Invokable} object should * be prepared for cases where the state has changed slightly, despite holding the read lock. This usually manifests * as race conditions where either a) some parallel unrelated bit of work has occured or b) duplicate work has * occured. The latter is only problematic if the operation is very expensive. * * @param <T> * @param invokable */ public <T> T withWrite(Invokable<T> invokable) { boolean readLockedAtEntry = releaseReadLock(); lock.writeLock().lock(); try { return invokable.invoke(); } finally { lock.writeLock().unlock(); restoreReadLock(readLockedAtEntry); } }
/** * As with {@link #withRead(Invokable)}, creating an {@link Invokable} wrapper around the runnable object. */ public void withRead(final Runnable runnable) { Invokable<Void> invokable = new Invokable<Void>() { @Override public Void invoke() { runnable.run(); return null; } }; withRead(invokable); }
/** * As with {@link #withWrite(Invokable)}, creating an {@link Invokable} wrapper around the runnable object. */ public void withWrite(final Runnable runnable) { Invokable<Void> invokable = new Invokable<Void>() { @Override public Void invoke() { runnable.run(); return null; } }; withWrite(invokable); }
public void run() { barrier.withRead(delegate); } }
@Override public Object invoke() { Object result = services.get(key); if (result == null) result = BARRIER.withWrite(create); return result; } };
public int readCounter() { return barrier.withRead(new Invokable<Integer>() { @Override public Integer invoke() { return getCounter(); } }); }
@Override public Object invoke() { Object result = services.get(key); if (result == null) result = BARRIER.withWrite(create); return result; } };
public int getCounter() { return barrier.withRead(new Invokable<Integer>() { @Override public Integer invoke() { return counter; } }); }