import java.util.logging.*;
public class Main {
public static final LicenseManager licenseManager = new LicenseManager();
static class LicenseManager {
private static final Logger logger =
Logger.getLogger(LicenseManager.class.getName());
private int apples = 10;
private int pies = 10;
private boolean enterpriseLoggingEnabled = true;
// Apples have high contention; so they get their own lock.
void useApple() {
checkExpired();
synchronized (appleLock) {
logger.
info("Using apple. Apples left: " + apples
+ ". " + Thread.
currentThread()); if (apples == 0) throw new InsufficientApplesException();
apples--;
}
}
/* Examples. There are lots of other operations like this
* on LicenseManager. We don't have time to prove that
* they are commutative, so we just use the main object lock
* around them all. The exception is when we find one with high
* contention, for example apples. */
synchronized void usePear() {checkExpired(); /*...*/}
synchronized void checkExpired() {}
synchronized void usePie() {
checkExpired();
logger.
info("Using pie. Pies left: " + pies
+ ". " + Thread.
currentThread()); if (pies == 0) throw new InsufficientPiesException();
boolean reallyCanUsePie = true; // do expensive pie computation
if (reallyCanUsePie) {
useApple(); /* using a pie requires an apple.
* TODO: stop putting apples in the pumpkin pie */
pies--;
}
}
synchronized boolean isEnterpriseLoggingEnabled() {
return enterpriseLoggingEnabled;
}
}
public static void main
(String[] args
) { // Install enterprise log handler on the root logger
Logger.getLogger("").addHandler(new Handler() {
@Override
public void publish(LogRecord lr) {
System.
out.
println("TEST." + lr.
getMessage() + ". " + Thread.
currentThread()); if (licenseManager.isEnterpriseLoggingEnabled())
System.
out.
println("ENTERPRISE ALERT! [" + lr.
getLevel() + "] " + lr.
getMessage() + ". " + Thread.
currentThread()); }
@Override public void flush() {}
});
// Simulate fat user
@Override
public void run() {
while (true) {
licenseManager.usePie();
}
}
}.start();
// Simulate fat albeit healthy user
while (true) {
licenseManager.useApple();
}
}
}