使用工厂方法的一个class
public class EnergySource {
private final long MAXLEVEL = 100;
private long level = MAXLEVEL;
private static final ScheduledExecutorService replenishTimer =
Executors.newScheduledThreadPool(10);
private ScheduledFuture<?> replenishTask;
private EnergySource() {
}
private void init() {
replenishTask = replenishTimer.scheduleAtFixedRate(new Runnable() {
public void run() {
replenish();
}
}, 0, 1, TimeUnit.SECONDS);
}
public static EnergySource create() {
final EnergySource energySource = new EnergySource();
energySource.init();
return energySource;
}
public long getUnitsAvailable() {
return level;
}
public boolean useEnergy(final long units) {
if (units > 0 && level >= units) {
level -= units;
return true;
}
return false;
}
public void stopEnergySource() {
replenishTask.cancel(false);
}
private void replenish() {
if (level < MAXLEVEL) level++;
}
}
//线程池中的线程默认为非守护线程,jvm不能做什么
Making the replenishTimer field static helped us share the pool of threads in the ScheduledThreadPoolExecutor. However, this leads to one complication: we have to figure out a way to shut it down. By default the executor threads run as nondaemon threads and will prevent the shutdown of the JVM if we don’t explicitly shut them down.
方法1 使用静态方法
public static void shutdown() { replenishTimer.shutdown(); }
There are two problems with this approach. The users of the EnergySource
have to remember to call this method. We also have to add logic to deal
with instances of EnergySource being created after the call to shutdown().
方法2 、add线程工厂参数 生成守护线程
We may pass an additional ThreadFactory parameter to the newScheduledThreadPool() method. This factory can ensure all the threads created are daemon threads, like so:
private static final ScheduledExecutorService replenishTimer =
Executors.newScheduledThreadPool(10,
new java.util.concurrent.ThreadFactory() {
public Thread newThread(Runnable runnable) {
Thread thread = new Thread(runnable);
thread.setDaemon(true);
return thread;
}
});
The main disadvantage of this approach is more code for us to write and maintain.
//guava api提供了一种自动退出的线程池
The Google Guava API (http://code.google.com/p/guava-libraries/), which provides quite a few convenience wrappers on top of the JDK concurrency API, also provides a method to create pools that exits automatically.