Java Threads
Author: Scott Oaks
Threads aren't a new idea: many operating systems and languages support them. But despite widespread support, threads tend to be something that everyone talks about, but few use. Programming with threads has a reputation for being tricky and nonportable.
Not so with Java. Java's thread facilities are easy to use, and -- like everything else in Java -- are completely portable between platforms. And that's a good thing, because it's impossible to write anything but the simplest applet without encountering threads. If you want to work with Java, you have to learn about threads.
This new edition shows you how to take full advantage of Java's thread facilities: where to use threads to increase efficiency, how to use them effectively, and how to avoid common mistakes.
Java Threads, 2nd Edition discusses problems like deadlock, race condition, and starvation in detail, helping you to write code without hidden bugs. It brings you up to date with the latest changes in the thread interface for JDK 1.2.
The book offers a thorough discussion of the Thread and ThreadGroup classes, the Runnable interface, the language's synchronized operator. It explains thread scheduling ends by developing a CPUSchedule class, showing you how to implement your own scheduling policy. In addition, Java Threads, 2nd Edition shows you how to extend Java's thread primitives. Other extended examples include classes that implement reader/writer locks, general locks, locks at arbitrary scope, and asynchronous I/O. This edition also adds extensive examples on thread pools, advanced synchronization technique, like condition variables, barriers, and daemon locks. It shows how to work with classes that are not thread safe, and pays special attention to threading issues with Swing. A new chapter shows you how to write parallel code for multiprocessor machines.
In short, Java Threads, 2nd Edition covers everything you need to know about threads, from the simplest animation applet to the most complex applications. If you plan to do any serious work in Java, you will find this book invaluable. Examples available online. Covers Java 2.
Library Journal
Cadenhead's Teach Yourself Java 2 in 24 Hours is a definite beginner's book, a self-tutorial in 24 one-hour chapters. The guides on networking, Threads (the ability of Java to multitask by allowing for multiple processes and actions at the same time), and Swing (a powerful Java interface package for visual design) are for advanced Java programmers but will fit well within most libraries. Copyright 1999 Cahners Business Information.
Library Journal
O'Reilly books have a reputation among programmers for providing some of the best technical information for professionals. No exception, these three web-related books will only enhance O'Reilly's reputation. JavaScript is not Java, but it is very useful because JavaScript code does not need to be compiled and the scripts can be embedded directly into an HTML document. Flanagan's work is an excellent book for programmers interested in learning it quickly. Grand, meanwhile, provides an exceptionally clear discussion of Java itself that is particularly useful for a working programmer moving from C++ to Java. Threads are what makes Java a particularly useful language for multiprocessingthe ability to appear to do more than one thing at a timewhich is what the Internet is all about. The tricky part of threads is that the concept is new for most users. Oaks offers a very clear discussion of how to spawn a process, when to spawn, and how to synchronize and schedule it, all illustrated with good network examples.
Table of Contents:
Preface1. Introduction to Threading
Java Terms 1
Thread Overview 3
Why Threads? 6
Summary 11
2. The Java Threading API
Threading Using the Thread Class 12
Threading Using the Runnable Interface 19
The Life Cycle of a Thread 24
Thread Naming 28
Thread Access 30
More on Starting, Stopping, and Joining 34
Summary 37
3. Synchronization Techniques
A Banking Example 40
Reading Data Asynchronously 44
A Class to Perform Synchronization 49
The Synchronized Block 53
Nested Locks 55
Deadlock 58
Return to the Banking Example 61
Synchronizing Static Methods 63
Summary 65
4. Wait and Notify
Back to Work (at the Bank) 67
Wait and Notify 68
wait(), notify(), and notifyAll() 74
wait() and sleep() 77
Thread Interruption 79
Static Methods (Synchronization Details) 85
Summary 86
5. Useful Examples of Java Thread Programming
Data Structures and Containers 88
Simple Synchronization Examples 93
A Network Server Class 101
The AsyncInputStream Class 108
Using TCPServer with AsyncInputStreams 121
Summary 122
6. Java Thread Scheduling
An Overview of Thread Scheduling 124
When Scheduling Is Important 135
Scheduling with Thread Priorities 138
Popular Scheduling Implementations 142
Native Scheduling Support 153
Other Thread-Scheduling Methods 157
Summary 167
7. Java Thread Scheduling Examples
Thread Pools 170
Round-Robin Scheduling 176
Job Scheduling 191
Summary 197
8. Advanced Synchronization Topics
Synchronization Terms 198
Preventing Deadlock 200
Lock Starvation 208
Thread-Unsafe Classes 222
Summary 234
9. Parallelizing for Multiprocessor Machines
Parallelizing a Single-Threaded Program 236
Inner-Loop Threading 255
Loop Printing 259
Multiprocessor Scaling 263
Summary 273
10. Thread Groups
Thread Group Concepts 274
Creating Thread Groups 275
Thread Group Methods 278
Manipulating Thread Groups 283
Thread Groups, Threads, and Security 285
Summary 291
A. Miscellaneous Topics
B. Exceptions and Errors
Index
A
accessing threads, 30-33
AccessNative class (example), 225
Account class (example), 41, 43, 52, 62
active threads, 34, 108, 279
activeCount( ) (Thread), 33, 279
activeGroupCount( ) (ThreadGroup), 280
add( ) (ThreadPool), 172
addItems( ) (ArrayTest; example), 224
addRequest( ) (ThreadPool), 172
addRequestAndWait( ) (ThreadPool), 172
alarms, 9
algorithms, parallelizable, 10
allowThreadSuspension( ) (ThreadGroup), 283
analysis of loops, 250-255
loop distribution, 251
loop isolation, 252
reimplementing loops, 254
Animate applet (example), 17, 22, 25-26, 33, 34
animation, 15, 141
(see also applets)
Applet class, 15-19
applets, 3
suspend( ) and resume( ), 157-161
TCPServer class and, 107
thread priorities in, 138
applications, 3
array of threads (see enumerate( ))
ArrayTest( ) (example), 224
associativity (mathematic), 248
asynchronous I/O, 44-49, 108-122
AsyncInputStream class (example), 110-121
TCPServer class with, 121
AsyncReadSocket class (example), 31, 45-46, 108, 114
atomic routines, 42
AutomatedTellerMachine class (example), 41, 62
auto-parallelizing MP C compiler, 245
available( )
AsyncInputStream class (example), 120
FilterInputStream class, 9
InputStream class, 44, 108
B
balancing load, 241-244
Barrier class (example), 94-98
barriers, 94-98, 198
Basic class (example), 267
blocked state, thread, 127
scheduling and, 189-191
suspended state, 157
blocking I/O, 8, 117
blocks, synchronized, 53-55, 57, 73
bound threads (Solaris), 151
browsers, 2, 286
BTree class (example), 215
BusyFlag class (example), 50-53, 57, 62, 67-70, 202, 213
development of, 50-58
preventing deadlock (example), 203-206
priority inheritance with, 221
C
CalcRequest class (example), 187
CalcServer class (example), 186-187
CalculateThread class (example), 284
calculation servers, 170
calls, priority, 139-142
cancel( ) ( JobScheduler; example), 195
checkAccess( ), 309
SecurityManager class, 286-287
Thread class, 309
ThreadGroup class, 309
child threads (see thread groups)
chunk scheduling (loops), 241
CircularList class (example), 91-93, 180
CircularListNode class (example), 91
circularly linked lists, 91-93
class locks (see classes, locking)
Class object, 65
classes
locking, 63-65, 202
network server, 101-108
scheduling and, 185
synchronized, 49-53, 93
ClassExample class (example), 64
classifying variables, 244-250
code, Java (see virtual machine)
collection classes, 93
synchronized collections, 223
competition for locks, 208-221
condition variables, 98-101, 198
CondVar class (example), 99-101
constructor, thread (see Thread( ))
Consumer class (example), 81
containers, 88-93
countStackFrames( ) (Thread), 295, 307
CPU Processing (see performance)
CPUScheduler class (example), 180-190
CPUSupport class (example), 154-156
thread pool with, 175
critical section, 199
current (running) thread, 131
currentThread( ) (Thread), 30-32
D
daemon thread groups, 282
daemon threads, 164, 186
DaemonLock class (example), 166, 196
data types, 88-93
DBAccess class (example), 214
deadlock, 54, 58-61, 200-208
locked threads terminating, 206-208
default
exception handler, 297-299
priority, 138
thread, 128, 131
delete( ) (CircularList; example), 92, 180
deleting threads and thread groups, 276, 281
dereferencing thread objects, 36
destroy( )
Thread class, 307
ThreadDeath class, 302
ThreadGroup class, 281
destroying threads, 299-303
distribution of loops, 251
dumpStack( ) (Thread), 295
E
end-of-file (EOF) indicator, 116, 119
enumerate( )
Thread class, 32
ThreadGroup class, 279-280
enumerating thread groups, 278-280
equal-priority threads, 130-132
yield( ) with, 161-164
errors (see exceptions)
event-dispatching threads, 227
event-related methods, 228
event variables, 198, 199
examples of thread scheduling, 169-197
job scheduling, 191-197
round-robin scheduling, 176-191
thread pools, 170-176
exception handler, 297-299
exceptions, 206, 304-310
execute( ), executeAt( ), executeIn( ) ( JobScheduler; example), 195
executeAtAndRepeat( ), executeInAnd-Repeat( ) ( JobScheduler; example), 195
exiting state, thread, 127, 184
explicit synchronization, 223-226
F
fairness in thread scheduling, 136-138
FilterInputStream class, 109
find( ), 93
finding thread groups, 278
Fractal applet (example), 140, 157-164
freeBusyFlag( ) (BusyFlag; example), 51, 53, 55-58, 70-71
QueuedBusyFlag class (example), 213
G
garbage collection, 36, 165
thread pools, 174
getBusyFlag( ) (BusyFlag; example), 51, 53-55, 70-74
QueuedBusyFlag class (example), 213
getBusyFlagOwner( ) (BusyFlag; example), 55-58
getMaxPriority( ) (ThreadGroup), 281
getName( )
Thread class, 28, 31
ThreadGroup class, 282
getParent( ) (ThreadGroup), 278
getPriority( ) (Thread), 139-142
getResource( ) (ResourceThrottle; example), 75
GetSystemInfo( ) (Windows), 155
getThreadGroup( ) (ThreadGroup), 278
global variables (see static variables)
graphical interfaces, 7
green-thread model, 135, 142-146, 190
groups, thread (see thread groups)
guided self-scheduling loops, 242
GuidedLoopInterchanged class (example), 267
H
hierarchy
lock, 202
thread, 275, 296
I
I/O (input/output), 8
IllegalArgumentException exception, 308
IllegalMonitorStateException exception, 308
IllegalThreadStateException exception, 307
image loading, 141
inheritance, 19, 24
priority inheritance, 132
from ThreadDeath class, 301
initial state, thread, 126
inner loops, 255-259
InputStream class, 44, 108
insert( ) (CircularList; example), 92, 180
instance variables, 4, 6
interactive programs, 125
interfaces, 20, 24
interpreter (see java interpreter)
interprocess communications (IPC), 89
interrupt( )
Thread class, 79-85
ThreadGroup class, 283-285
interrupted( ) (Thread), 80
InterruptedException exception, 80, 305
InterruptedIOException exception, 82, 305
interrupting threads, 79-85
inversion of thread priority, 132, 221-222
invokeAndWait( ), 229, 234
invokeLater( ), 231
I/O (input/output), 8
asynchronous, 44-49, 108-122
blocking I/O, 8, 117
interrupted, 82-85
InterruptedIOException exception, 305
I/O-intensive programs, 125
IOException, 116, 119
IPC (interprocess communications), 89
isActive( ), 23
isAlive( )
this reference and, 28
Thread class, 24-26, 34
isDaemon( )
Thread class, 165
ThreadGroup class, 282
isDestroyed( ) (ThreadGroup), 281
isInterrupted( ), 80
isolation, loop, 252
J
Java Foundation Classes, 226
java interpreter, 2
scheduling (see scheduling threads)
Java, definition of, 1
JDBC-ODBC bridge, 225
JFC, single-thread access with, 226
job scheduling, 191-197
JobScheduler class (example), 191-196
join( ) (Thread), 27-28, 36-37, 305
barrier synchronization example, 94
this reference and, 28
joining threads, 26-28, 36-37
jre interpreter, 2
K
Kitchen class (example), 200-202, 203-206
L
level, priority (see priority, thread)
lightweight processes (LWPs), 149-153
linked lists, 91-93
of thread priorities, 130
list of threads (see enumerate( ))
list( )
Thread class, 296
ThreadGroup class, 280
listing threads in groups, 278-280
load balancing, 241-244
loading images, 141
local variables, 4, 6
locks, 199
barriers, 94-98, 198
class locks, 63-65
condition variables, 98-101, 198
deadlock, 54, 58-61, 200-208
held by terminating threads, 206-208
hierarchy of, 202
IllegalMonitorStateException, 308
lock starvation, 208-221
priority-inverting locks, 221-222
mutex, 43, 199
nested, 55-58, 61
reader-writer, 199, 215-221
releasing without scheduling event, 211
scope of, 49
LockTest class (example), 145
LoopHandler class (example), 239
LoopPrinter class (example), 271
loops
analysis and transformation, 250-255
loop distribution, 251
loop isolation, 252
reimplementing loops, 254
inner-loop threading, 255-259
loop-private variables, 245
multilayered, 253
parallelizing, 10
printing with, 259-263, 271
scheduling, 241-244
lwp threading model (see green thread model)
LWPs (lightweight processes), 149-153
M
main( ), 3, 15
makeCookie( ) (Kitchen; example), 200, 203-205
makeOmelette( ) (Kitchen; example), 200, 204
MAX_PRIORITY variable, 138, 280
maximum thread priority, 138, 280
MediaTracker class, 174
memory, shared, 90
message queues, 89
methods
scope of, 49
static, 63-65, 78-86
synchronized, 52, 57, 69, 201
(see also synchronization)
MIN_PRIORITY variable, 138
monitors, 199
(see also locks)
MsgQueue class (example), 89
multilayered loops, 253
multiplexing, 8
multiprocessor machines, 7, 235-273
inner-loop threading, 255-259
loop printing, 259-263, 271
multiprocess scaling, 263-273
single-threaded programs, 236-255
loop analysis and transformation, 250-255
loop scheduling and load balancing, 241-244
variable classification, 244-250
multitasking, 3-5, 89
multithreading, 5-6
activeCount( ) (Thread), 33
lock starvation, 208-221
multiple CPU-intensive threads, 141
multiprocessor machines and, 235-273
inner-loop threading, 255-259
loop printing, 259-263, 271
multiprocess scaling, 263-273
single-threaded programs, 236-255
notify( ) and, 74-77
reader-writer locks, 199, 215-221
single-thread access, 226-234
thread life cycle, 24-28
mutex (mutually exclusive) locks, 43, 199
MyJoinApplet applet (example), 36
MyServer class (example), 107
MyStatic class (example), 64
MyStaticClass class (example), 86
MyThread class (example), 210
N
names, thread, 28-30
nanosecond counting, 17
native-thread model, 135, 153-156
32-bit Windows, 146-149
Solaris, 149-153
nested locks, 55-58, 61
network sockets, 44, 101-108
nonblocking I/O, 8
NORM_PRIORITY variable, 138
notify( ) (Object), 68-87, 308
multiple threads and, 74-77
in static methods, 85
notifyAll( ) (Object), 74-77, 119, 214, 308
NullPointerException exception, 309
number of threads (see activeCount( ); enumerate( ))
O
Object class, 69
objects, 6
locking, 48, 56, 63
(see also instance variables)
OurApplet applet (example), 12, 20-21
OurClass class (example), 12-14, 20
P
parallelizable algorithms, 10
parallelizing for multiprocessor machines, 235-273
inner-loop threading, 255-259
loop printing, 259-263, 271
multiprocess scaling, 263-273
single-threaded programs, 236-255
loop analysis and transformation, 250-255
loop scheduling and load balancing, 241-244
variable classification, 244-250
parent threads (see thread groups)
parentOf( ) (ThreadGroup), 278
performance, 7, 123
load balancing, 241-244
lock starvation, 208-221
multiple CPU-intensive threads, 141
scaling and, 265-269
synchronizing classes, 93
(see also scheduling threads)
polling, 9
PoolLoopHandler class (example), 256
PoolSelfLoopHandler class (example), 257
printing thread information, 296
printing with loops, 259-263, 271
priority, thread, 127-129
equal-priority threads, 130-132
yield( ) with, 161-164
lock starvation and, 212
priority inheritance, 132
priority inversion, 132, 221-222
round-robin scheduling, 133, 136-138
examples, 176-191
scheduling by, 138-142
thread groups and, 280
threading models, 134-135
green-thread model, 135, 142-146, 190
native-thread model, 135, 146-153
variables for, 138
PriorityBusyFlag class (example), 221
private variables (see local variables)
ProcessIt class (example), 95-97
programs, 2, 125
Q
QueuedBusyFlag class (example), 213
queues, message, 89
R
race conditions, 35, 46-47
reduction variables, 247
stopping stopped threads, 35
wait and notify mechanism, 69, 72
read( ), 8
read-only variables, 245
reader-writer locks, 199, 215-221
reduction variables, 247-250
references, 56, 108
reimplementing loops, 254
removeThread( ) (CPUScheduler; example), 183-185
removeUseless( ) (example), 59
repaint( ), 233
ResourceThrottle class (example), 75
restarting threads, 35
resume( )
Thread class, 157-161
ThreadGroup class, 283-285
round-robin scheduling, 133, 136-138, 176-191, 212
routines, atomic, 42
run( ), 12-15
CPUScheduler class (example), 182-185
isAlive( ) and, 26
StockHandler class (example), 84
synchronizing, 48-49
TCPServer class (example), 105
Thread class, 297, 310
ThreadPool class (example), 171
Runnable interface, 20-23, 104, 108
thread pools and, 174
runnable state, thread, 126
run-time exceptions, 206, 306
RuntimeException exception, 306
RWLock class (example), 217
RWNode class (example), 216
S
ScaleTest class (example), 265-269
scaling multiprocessors, 263-273
scheduling threads, 124-167
equal-priority threads, 130-132
yield( ) with, 161-164
examples of, 169-197
fairness, 136-138
job scheduling, 191-197
native scheduling support, 153-156
by priority, 138-142
priority inheritance, 132
priority inversion, 132, 221-222
round-robin scheduling, 133, 136-138, 212
examples, 176-191
suspend( ) and resume( ), 157-161
synchronization and, 183
thread pools, 170-176
threading models, 134-135
green-thread model, 135, 142-146, 190
native-thread model, 135, 146-153
yield( ), 161-164
(see also priority, thread)
SchedulingExample class (example), 128-129
scope of a lock, 49
security, 285-291
SecurityException exception, 309
SecurityManager class, 285-287
SelfLoopHandler class (example), 242
self-scheduling loops, 242
semaphores, 58, 199
serialization, scaling and, 264
ServerHandler class (example), 106, 121
thread groups and, 284
servers, network, 101-108
ServerSocket object, 104
setDaemon( )
Thread class, 165, 307
ThreadGroup class, 282
setMaxPriority( ) (ThreadGroup), 281
setName( ), 28
setPriority( ) (Thread), 138-142, 185, 308, 309
setResource( ) (ResourceThrottle; example), 75
setup time (for scaling), 263
shared memory, 90
shared variables, 247, 250
ShareMemory class (example), 90
shutdown( ), 85
signals, 9
SimpleScheduler class (example), 177
simultaneous execution, 6
single-thread access, 226-234
single-threaded programs, parallelizing, 236-255
loop analysis/transformation, 250-255
loop scheduling and load balancing, 241-244
variable classification, 244-250
SinTable class (example), 236-238, 240, 244-252, 258, 260, 262
skip( ), 120
sleep( )
Applet class, 16-18, 23
Thread class, 78, 305
sockets, 44, 101-108
Solaris native-threading model, 149-153, 156
stack, thread, 295
start( )
Applet class, 14, 19, 34-35
Thread class, 297, 307
startServer( ) (TCPServer; example), 104
starvation, lock, 208-221
priority-inverting locks, 221-222
state, thread, 126
IllegalThreadStateException, 307
suspend( ) and resume( ) and, 157-161
thread groups and, 283-285
yield( ) and, 161-164
static methods, 63-65, 78-86
(see also methods)
static scheduling (loops), 241
static variables, 4, 6
staticNotify( ) (example), 86
staticWait( ) (example), 86
StockHandler class (example), 83-85
StockObservable class (example), 83-85
stop( )
Applet class, 18-19, 26, 34-37
isAlive( ) and, 26
Thread class, 309, 310
ThreadDeath class, 300, 301
ThreadGroup class, 283-285
stopping threads, 35-37, 299-302
garbage collection and, 36
interrupting threads, 79-85
(see also stop( ))
stopServer( ) (TCPServer; example), 104
storeback variables, 246
scaling performance and, 270
suspend( )
Thread class, 157-161
ThreadGroup class, 283-285
suspended state, thread, 157
SwingTest class (example), 229, 231
symbolic priority values, 139
synchronization, 49-66, 198
barriers, 94-98, 198
of blocks, 53-55, 57, 73
of classes, 49-53, 93
condition variables (example), 98-101
deadlock (see deadlock)
of linked lists, 92
of methods, 52, 57, 69, 201
static methods, 63-65, 78-86
TCPServer class and, 107
thread scheduler and, 183
thread-unsafe classes, 222-234
explicit synchronization for, 223-226
single-thread access, 226-234
wait and notify mechanism, 69-74
synchronized keyword, 205
system-level threads, 144, 149
system thread group, 275
T
TargetNotify class (example), 76
TCPServer class (example), 102-108, 175, 186
applets and, 107
AsyncInputStream class with, 121
thread groups with, 277
terminating locked threads, 206-208
Test class (example), 178, 182, 210
TestRead class (example), 32
TestThread class (example), 124-126, 177-179, 181
this reference, join( ) and isAlive( ) with, 28
Thread( ), 14, 21, 29
Thread class, 13-19, 286
thread groups, 274-293
creating, 275-278
daemon thread groups, 282
destroying, 281
enumerating threads in, 278-280
finding, 278
manipulating, 283-285
priority and, 280
security and, 285-291
thread pools, 170-176
ThreadDeath class, 299-302
ThreadGroup class, 274, 291-293
methods of, 278-285
threading models, 134-135
green-thread model, 135, 142-146, 190
native-thread model, 135, 146-153
round-robin scheduling, 133, 136-138, 176-191, 212
ThreadPool class, 170-176
threads, 3-6
accessing specific, 30-33
active (see active threads)
current thread, 30-32
daemon versus user, 164
data types for (see data types)
deadlocked (see deadlock)
default, 128, 131
destroying, 299-303
enumerating thread groups, 278-280
getting list of (see enumerate( ))
groups of (see thread groups)
hierarchy of, 275, 296
interrupting, 79-85
joining, 26-28, 36-37
life cycle of, 24-28
multiple (see multithreading)
multiprocessor machines and, 235-273
inner-loop threading, 255-259
loop printing, 259-263, 271
multiprocess scaling, 263-273
naming, 28-30
native scheduling support, 153-156
number of (see activeCount( ))
popular scheduling implementa-tions, 142-153
green-thread model, 142-146
Solaris native threads, 149-153
Windows native threads, 146-149
priority (see priority, thread)
putting to sleep (see sleep( ))
restarting, 35
scheduling examples, 169-197
job scheduling, 191-197
round-robin scheduling, 176-191
thread pools, 170-176
single-threaded programs, 236-255
loop analysis and
transformation, 250-255
loop scheduling and load balancing, 241-244
variable classification, 244-250
stack information, 295
stopping, 18-19, 35-37
system- and user-level, 144, 149
thread-unsafe classes, 222-234
explicit synchronization for, 223-226
single-thread access, 226-234
timeouts, 9, 77-79
timers, 9, 15, 136-138, 177-179
TimerThread class (example), 16, 28
timesliced behavior (see round-robin scheduling)
toString( ) (Thread), 296
transformation, loops, 250-255
loop distribution, 251
loop isolation, 252
reimplementing loops, 254
tryGetBusyFlag( )
BusyFlag class (example), 53
QueuedBusyFlag class (example), 213
tryGetBusyFlag( ) (BusyFlag; example), 72
U
uncaughtException( )
Thread class, 298
ThreadGroup class, 282
updateFolders( ) (example), 59
user threads, 164
user-defined scheduler (loops), 243
user-level threads, 144, 149
(see also green-thread model)
V
variables, 4
classification of, 244-250
condition variables, 98-101, 198
global (see static variables)
loop-private, 245
private (see local variables)
read-only, 245
reduction, 247-250
shared, 247, 250
storeback variables, 246, 270
thread priority, 138
Vector class (example), 212, 213
virtual machine, 2
daemon versus user threads, 165
enumerating threads in, 32
scaling and, 264
W
wait( ) (Object), 68-87, 305, 308
in static methods, 85
WaitExample class (example), 78
waitForAll( ) (ThreadPool), 173, 174
waking up threads (see notify( ), notifyAll( ))
web browsers, 2
SecurityManager class and, 286
Windows native-threading model, 146-149, 155
Y
yield( ) (Thread), 161-164
New interesting book: HTML Utopia or Take Back Your Life Special Edition
Mastering Digital Black and White: A Photographer's Guide to High Quality Black-and-White Imaging and Printing
Author: Amadou Diallo
The very nature of black and white photography places a premium on creative interpretation of the image. Advances in digital technology have expanded both the precision of imaging techniques and the interpretive possibilities for black and white imagery. Never before has such a wide array of tools been available to photographers who have a passion for black and white. Mastering Digital Black and White is written for these photographers. It serves not only as a comprehensive guide for creating black and white images and prints, but also examines the role of artistic craft in the imaging process. Learn how to employ your digital tools as extensions of your photographic vision. Read in-depth interviews with, and view images from, five accomplished photographers as they discuss their process and inspirations. Prepare to indulge your passion for gallery-quality black-and-white images in the digital darkroom.
No comments:
Post a Comment