Applet间的通讯(2)--Tricks of the Java Programming Gurus
来源:互联网 发布:显微镜图像软件 编辑:程序博客网 时间:2024/05/13 14:37
Tricks
of the
Java Programming Gurus
by Glenn L. Vanderburg. et al.
1.Applet间的通讯(2)
相互查找
使用静态变量进行通讯并不意味着applet就可以同时被初始化。不同的实例还是先后启动的,我们并不能保证它们的启动次序。然而,有一点我们可以确定:在第一个ColorRelay applet实例被创建之前,类ColorRelay已经初始化了,因此,当所有applet实例启动时,它们都将获得类的静态变量。
但是,当你使用静态变量时必须小心,因为多个实例可能同时访问静态变量。为了解决这个问题,我使用了两个同步方法(synchronized methods)从链表中增减applet实例。因为它们是synchronized static方法,当它们运行时,ColorRelay 类会被索住,以避免并发访问。清单1.3是这两个方法的代码。值得注意的是,当第一个元素被加到链表之后,主控线程(controller thread)将启动。我们随后会看到当最后一个元素从链表中被移出后,这个线程将自动停止。
清单 1.3. ColorRelay.java (part 2).
/**
* Adds an instance to the list of active instances maintained in the
* class. No check is made to prevent adding the same instance twice.
* @param elem the ColorRelay instance to add to the list.
* @see #removeFromList
*/
static synchronized void addToList(ColorRelay elem) {
if (list == null) {
list = listTail = elem;
elem.next = elem.prev = null;
// Because the list has elements now, we should start the thread.
relayer = new Thread(new ColorRelay());
relayer.start();
}
else {
elem.prev = listTail;
listTail.next = listTail = elem;
elem.next = null;
}
}
/**
* Removes an instance from the list of active instances maintained in
* the class. Works properly but does <em>not</em> signal an error if
* the element was not actually on the list.
* @param elem the ColorRelay instance to be removed from the list.
* @see #addToList
*/
static synchronized void removeFromList(ColorRelay elem) {
ColorRelay curr = list;
while (curr != null && curr != elem) {
curr = curr.next;
}
if (curr == elem) { // We found it!
if (list == curr) {
list = curr.next;
}
if (listTail == curr) {
listTail = curr.prev;
}
if (curr.next != null) {
curr.next.prev = curr.prev;
}
if (curr.prev != null) {
curr.prev.next = curr.next;
}
curr.next = curr.prev = null;
}
// If curr is null, then the element is not on the list
// at all. We could treat that as an error, but I'm
// choosing to report success.
return;
}
初始化共享数据
Applet被创建之后init方法被调用,这个方法检查、转换和存储applet的参数。对image参数需要额外的注意,因为它是存储在另一个静态变量中的。在试图访问originalImage静态变量之前,要锁住ColorRelay类,我们没有使用synchronized 方法,而是使用一段synchronized 监测语句来实现这个目的。(事实上,应该只有一个ColorRelay实例获得image参数,但为了防止HTML中的编码错误,我们采取了上述的预防措施)。清单1.4是init的代码。
清单 1.4. ColorRelay.java (part 3).
/**
* Initializes the applet instance. Checks and stores
* parameters and initializes other instance variables.
*/
public void init() {
String flash = getParameter("flashColor");
if (flash != null) {
try {
flashColor = new Color(parseRGB(flash));
}
catch (NumberFormatException e) {
// Ignore a bad parameter and just go with the default.
}
}
String sleep = getParameter("sleepTime");
if (sleep != null) {
try {
sleepSecs = Integer.parseInt(sleep);
}
catch (NumberFormatException e) {
// Ignore a bad parameter and just go with the default.
}
}
String imageURL = getParameter("image");
if (imageURL != null) {
Class cr = Class.forName("COM.MCP.Samsnet.tjg.ColorRelay");
synchronized (cr) {
if (originalImage == null) {
originalImage = getImage(getDocumentBase(), imageURL);
}
}
}
tracker = new MediaTracker(this);
}
Working Together
当浏览器准备执行applet时,start 方法被调用,将applet加入链表。在stop方法中,applet被译出链表。在前面的代码中你已经看到,第一个链表元素的添加将导致控制线程的启动。这个控制线程仅仅是循环读取链表元素,一次将链表中的某个元素点亮(显示彩色图片)。至于显示的持续时间,是由applet自己决定的。如果链表中没有元素了,控制线程自动终止。清单1.5是控制线程的strat、stop以及run方法。
清单 1.5. ColorRelay.java (part 4).
/**
* Starts the applet running. The ColorRelay hooks up with
* other instances on the same page and begins coordinating
* when this method is called.
*/
public void start() {
// Ordinarily, we want to display the original image.
image = originalImage;
ColorRelay.addToList(this); // Let's get to work!
}
/**
* Stops the applet. The ColorRelay instance removes itself from the
* group of cooperating applets when this method is called.
*/
public void stop() {
ColorRelay.removeFromList(this);
}
/**
* Loops through the list of active instances for as long as it is
* non-empty, calling each instance's 'flash' method.
* @see #flash
*/
public void run () {
ColorRelay curr;
// Continue running through the list until it's empty ...
while (list != null) {
for (curr = list; curr != null; curr = curr.next) {
try {
curr.flash();
}
catch (InterruptedException e) {
}
}
}
}
翻译:chenyuan_tongji (chenyuan_tongji@sina.com)
- Applet间的通讯(2)--Tricks of the Java Programming Gurus
- Applet间的通讯(1)--Tricks of the Java Programming Gurus
- Tricks of the Windows game programming gurus
- Tricks of the Microsoft Office 2007 Gurus (Business Solutions)
- Guru of the Unix gurus
- The first Java programming of mine
- 《The Art of Computer Programming》的PREFACE
- 科学的编程-the science of programming
- The Tao of Programming
- The Tao of Programming
- The Tao of Programming
- The Paradigms of Programming
- The Tao of Programming
- The Tao of Programming
- The World of Programming
- The practice of programming
- The Tao Of Programming
- The total tricks of database development(Important)
- BorCon 2003 Report (in San Jose, November 1-5, 2003)
- 走进Borland!
- 使用UltraEdit和gcc构造简易IDE
- 随即整数的生成
- Applet间的通讯(1)--Tricks of the Java Programming Gurus
- Applet间的通讯(2)--Tricks of the Java Programming Gurus
- 对JSP Model 2工作流程的一些体会
- 奔腾IV处理器架构剖析
- 用vector取代C-style的数组
- 基于LOD的大规模真实感室外场景实时渲染技术的初步研究(1)
- 预编译头文件的使用
- 基于LOD的大规模真实感室外场景实时渲染技术的初步研究 PART I
- 基于LOD的大规模真实感室外场景实时渲染技术的初步研究 part II&III
- 如何投影一个纹理