@@ -6,7 +6,7 @@ An implicit assumption in everything we’ve done so far is that a single progra
Although the language used to describe threads suggests that their purpose is to allow several things to happen simultaneously, this is a somewhat misleading impression. Even the smallest Java application running on Sun ’s JDK platform, for example, has five threads, and that’s only if the application has not created any itself, and even if the machine on which the program runs consists of a single processor (which can only execute one instruction at a time). The four additional “system threads” perform a number of tasks (such as “finalizing” objects that are no longer reachable by the program) that are logically independent of the rest of the program.Their actions could usefully occur at any time relative to the rest of the program.Sun’s Java run time system, in other words, is using threads as a organizational tool for its system.
Threads abound in Java programs that use graphical user interfaces(GUIs). One thread draws or redraws the screen. Another responds to events such as the clicking of a mouse button at some point on the screen. These are related,but largely independent activities: objects must be redrawn, for example, whenever a window becomes invisible and uncovers them, which happens independently of any calculations the program is doing.Threads violate our implicit assumption that a single program operates on our data, so that even an otherwise perfectly implemented data structure, with all of its instance variables private, can become corrupted in rather bizarre ways. The existence of multiple threads operating on the same data objects also raises the general problem of how these threads are to communicate with each other in an orderly fashion.
Threads abound in Java programs that use graphical user interfaces(GUIs). One thread draws or redraws the screen. Another responds to events such as the clicking of a mouse button at some point on the screen. These are related,but largely independent activities: objects must be redrawn, for example, whenever a window becomes invisible and uncovers them, which happens independently of any calculations the program is doing.Threads violate our implicit assumption that a single program operates on our data, so that even an otherwise perfectly implemented data structure, with all of its instance variables private, can become corrupted in rather bizarre ways. The existence of multiple threads operating on the same data objects also raises the general problem of how these threads are to communicate with each other in an orderly fashion.
## 10.1 Synchronized Data Structures
...
...
@@ -139,7 +139,7 @@ public synchronized Object receive ()
}
```
The methods of `SmallMailbox` allow other threads in only at carefully controlled points: the calls to wait. For example, the loop in `deposit` means “If there is still old unreceived mail, wait until some other thread to receives it and wakes me up again (with `notifyAll`) and I have managed to lock this mailbox again.” From the point of view of a thread that is executing `deposit` or `receive`, each call to `wait` has th e effect of causing some change to the in stance variables of `this`—some change, that is, that could be effected by other calls `deposit` or `receive`.
The methods of `SmallMailbox` allow other threads in only at carefully controlled points: the calls to wait. For example, the loop in `deposit` means “If there is still old unreceived mail, wait until some other thread to receives it and wakes me up again (with `notifyAll`) and I have managed to lock this mailbox again.” From the point of view of a thread that is executing `deposit` or `receive`, each call to `wait` has the effect of causing some change to the instance variables of `this`—some change, that is, that could be effected by other calls `deposit` or `receive`.
As long as the threads of a program are careful to protect all their data in monitors in this fashion, they will avoid the sorts of bizarre interaction described at the beginning of §10.1. Of course, there is no such thing as a free lunch; the use of locking can lead to the situation known as deadlock in which two or more threads wait for each other indefinitely, as in this artificial example:
Although the language used to describe threads suggests that their purpose is to allow several things to happen simultaneously, this is a somewhat misleading impression. Even the smallest Java application running on Sun ’s JDK platform, for example, has five threads, and that’s only if the application has not created any itself, and even if the machine on which the program runs consists of a single processor (which can only execute one instruction at a time). The four additional “system threads” perform a number of tasks (such as “finalizing” objects that are no longer reachable by the program) that are logically independent of the rest of the program.Their actions could usefully occur at any time relative to the rest of the program.Sun’s Java run time system, in other words, is using threads as a organizational tool for its system.
尽管用于描述线程的语言表明,线程的目的是允许同时发生几件事情,但这在一定程度上是一种误导。即使是最小的Java应用程序运行在 Sun 的 JDK 的平台上,例如,有五个线程,这是只有在应用程序没有创建任何本身,即使程序运行的机器由一个单处理器(一次只能执行一个指令)。这四个额外的“系统线程”执行许多任务(例如“finalizing”对象是程序不再可访问),这些任务在逻辑上独立于程序的其余部分。相对于程序的其余部分,它们的操作可以在任何时候有效地发生。换句话说,Sun的Java运行时系统使用线程作为其系统的组织工具。
Threads abound in Java programs that use graphical user interfaces(GUIs). One thread draws or redraws the screen. Another responds to e vents such as the clicking of a mouse button at some point on the screen. These are related,but largely independent activities: objects must be redrawn, for example, whenever a window becomes invisible and uncovers them, which happens independently of any calculations the program is doing.Threads violate our implicit assumption that a single program operates on our data, so that even an otherwise perfectly implemented data structure, with all of its instance variables private, can become corrupted in rather bizarre ways. The existence of multiple threads operating on the same data objects also raises the general problem of how these threads are to communicate with each other in an orderly fashion.
Thus, we lose the value that Program 2 set, because it puts this value into the old value of `data` after `data’s` contents have been copied to the new expanded array. To solve the simple problem presented by `ArrayList`, threads can arrange to access any particular `ArrayList` in mutual exclusion—that is, in such a way that only one thread at a time operates on the object. Java’s `synchronized` statement provide mutual exclusion, allowing us to produce `synchronized` (or thread-safe) data structures. Here is part of an example, showing both the use of the `synchronized` method modifier and equivalent use of the synchronized statement:
The objects returned by the `synchronizedList` method are examples of the simplest kind of monitor. This term refers to an object (or type of object) that controls (“monitors”) concurrent access to some data structure so as to make it work correctly. One function of a monitor is to provide mutually exclusive access to the operations of the data structure, where needed. Another is to arrange for synchronization between threads—so that one thread can wait until an object is “ready” to provide it with some service.
@@ -142,14 +132,9 @@ public synchronized Object receive ()
}
```
The methods of `SmallMailbox` allow other threads in only at carefully controlled points: the calls to wait. For example, the loop in `deposit` means “If there is still old unreceived mail, wait until some other thread to receives it and wakes me up again (with `notifyAll`) and I have managed to lock this mailbox again.” From the point of view of a thread that is executing `deposit` or `receive`, each call to `wait` has th e effect of causing some change to the in stance variables of `this`—some change, that is, that could be effected by other calls `deposit` or `receive`.
As long as the threads of a program are careful to protect all their data in monitors in this fashion, they will avoid the sorts of bizarre interaction described at the beginning of §10.1. Of course, there is no such thing as a free lunch; the use of locking can lead to the situation known as deadlock in which two or more threads wait for each other indefinitely, as in this artificial example:
In the case of general monitors, “exchanging data” means setting variables that each can see. If we take the idea further, we can in stead define “exchanging data” as “reading input and writing output.” We get a concurrent programming discipline called message passing.