1. Count类
//使用单个的Count对象来跟踪花园参观者的主计数值
class Count {
private int count = 0;
// Count.incrementO和Count.valueO都是synchronized的,用来控制对count域的访问。
public synchronized int increment() {
int temp = count;
return (count = ++temp);
}
public synchronized int value() {
return count;
}
}
2. 入口计数任务
class Entrance implements Runnable {
//Count对象当作Entrance类中的一个静态域进行存储
private static Count count = new Count();
//入口任务队列
private static List<Entrance> entrances = new ArrayList<Entrance>();
//每个Entrance任务都维护着一个本地值number
//它包含通过某个特定入口进入的参观者的数量
private int number = 0;
// Doesn't need synchronization to read:
private final int id;
//因为Entrance.canceled是一个volatile布尔标志, 而它只会被读取和赋值(不会与其他域组
//合在一起被读取),所以不需要同步对其的访问,就可以安全地操作它。
private static volatile boolean canceled = false;
// Atomic operation on a volatile field:
public static void cancel() {
canceled = true;
}
// 在构造函数中将任务加入到任务List
public Entrance(int id) {
this.id = id;
// Keep this task in a list. Also prevents
// garbage collection of dead tasks:
entrances.add(this);
}
//多线程任务各自拥有自己的run方法,而静态域对象是共享的,非静态域对象是属于线程各自的
//Entrance.run()只是递增number和count对象,然后休眠100毫秒。
public void run() {
while (!canceled) {
synchronized (this) {
++number;
}
//在人们通过十字转门时,将显示总人数和通过每个入口的人数
//每个入口任务计数值加一 主计数值加一
print(this + " Total: " + count.increment());
try {
TimeUnit.MILLISECONDS.sleep(100);
} catch (InterruptedException e) {
print("sleep interrupted");
}
}
print("Stopping " + this);
}
public synchronized int getValue() {
return number;
}
public String toString() {
return "Entrance " + id + ": " + getValue();
}
public static int getTotalCount() {
return count.value();
}
public static int sumEntrances() {
int sum = 0;
for (Entrance entrance : entrances)
sum += entrance.getValue();
return sum;
}
}
3. OrnamentGarden类
public class OrnamentalGarden {
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++)
exec.execute(new Entrance(i));
// Run for a while, then stop and collect the data:
TimeUnit.SECONDS.sleep(3);
//在3秒钟之后, main() 向Entrance发送static cancel()消息
Entrance.cancel();
//调用exec对象的shutdown()方法
exec.shutdown();
//之后调用exec上的awaitTermination()方法
if (!exec.awaitTermination(250, TimeUnit.MILLISECONDS))
print("Some tasks were not terminated!");
//尽管这会导致每个任务都退出其run()方法,并因此作为任务而终止,
// 但是.Entrance对象仍旧是有效的,因为在构造器中,每个Entrance对象都存储在称为entrances的
// 静态List<Entrance>中。因此, sumEntrances()仍旧可以作用于这些有效的Entrance对象。
print("Total: " + Entrance.getTotalCount());
print("Sum of Entrances: " + Entrance.sumEntrances());
}
}
这个程序已经看过三四遍了,但是我仍旧没有很好的理解。今天总结一下。
首先看类图
如果没看类图,好多细节的部分其实都没有弄清楚的
1. Count.increment()和Count.value()都是synchronized的,用来控制对count域的访问
2. Entrance类中 count, entrances, canceled都是static修饰,所有线程共享。
cancel方法 getTotalCount方法 sumEntrances方法都是static的方法
3. 在构造器中,每个Entrance对象都存储在称为entrances的静态List<Entrance>中。这样,即便每个任务退出其run方法,Entrance对象仍然是有效的, sumEntrances()仍旧可以作用于这些有效的Entrance对象(之前从来没有想过在类中用一个static List来存储多个自身对象!)
真正理解一个程序的方法是把它写出来,并且能够不断地进行重构