Java Concurrency in Practice Quotes

Rate this book
Clear rating
Java Concurrency in Practice Java Concurrency in Practice by Brian Goetz
2,341 ratings, 4.45 average rating, 117 reviews
Open Preview
Java Concurrency in Practice Quotes Showing 1-30 of 67
“It is far easier to design a class to be thread-safe than to retrofit it for thread safety later.”
Brian Goetz, Java Concurrency in Practice
“Just as it is a good practice to make all fields private unless they need greater visibility, it is a good practice to make all fields final unless they need to be mutable.”
Brian Goetz, Java Concurrency in Practice
“Sometimes abstraction and encapsulation are at odds with performance — although not nearly as often as many developers believe — but it is always a good practice first to make your code right, and then make it fast.”
Brian Goetz, Java Concurrency in Practice
“Locking can guarantee both visibility and atomicity; volatile variables can only guarantee visibility.”
Brian Goetz, Java Concurrency in Practice
“Whenever more than one thread accesses a given state variable, and one of them might write to it, they all must coordinate their access to it using synchronization.”
Brian Goetz, Java Concurrency in Practice
“Immutable objects are simple. They can only be in one state, which is carefully controlled by the constructor. One of the most difficult elements of program design is reasoning about the possible states of complex objects. Reasoning about the state of immutable objects, on the other hand, is trivial.

Immutable objects are also safer. Passing a mutable object to untrusted code, or otherwise publishing it where untrusted code could find it, is dangerous — the untrusted code might modify its state, or, worse, retain a reference to it and modify its state later from another thread. On the other hand, immutable objects cannot be subverted in this manner by malicious or buggy code, so they are safe to share and publish freely without the need to make defensive copies.”
Brian Goetz, Java Concurrency in Practice
“The possibility of incorrect results in the presence of unlucky timing is so important in concurrent programming that it has a name: a race condition. A race condition occurs when the correctness of a computation depends on the relative timing or interleaving of multiple threads by the runtime; in other words, when getting the right answer relies on lucky timing.”
Brian Goetz, Java Concurrency in Practice
“Compound actions on shared state, such as incrementing a hit counter (read-modify-write) or lazy initialization (check-then-act), must be made atomic to avoid race conditions. Holding a lock for the entire duration of a compound action can make that compound action atomic. However, just wrapping the compound action with a synchronized block is not sufficient; if synchronization is used to coordinate access to a variable, it is needed everywhere that variable is accessed. Further, when using locks to coordinate access to a variable, the same lock must be used wherever that variable is accessed.”
Brian Goetz, Java Concurrency in Practice
“When a field is declared volatile, the compiler and runtime are put on notice that this variable is shared and that operations on it should not be reordered with other memory operations. Volatile variables are not cached in registers or in caches where they are hidden from other processors, so a read of a volatile variable always returns the most recent write by any thread.”
Brian Goetz, Java Concurrency in Practice
“Debugging tip: For server applications, be sure to always specify the -server JVM command line switch when invoking the JVM, even for development and testing. The server JVM performs more optimization than the client JVM, such as hoisting variables out of a loop that are not modified in the loop; code that might appear to work in the development environment (client JVM) can break in the deployment environment (server JVM).”
Brian Goetz, Java Concurrency in Practice
“From the perspective of a class C, an alien method is one whose behavior is not fully specified by C. This includes methods in other classes as well as overrideable methods (neither private nor final) in C itself. Passing an object to an alien method must also be considered publishing that object. Since you can’t know what code will actually be invoked, you don’t know that the alien method won’t publish the object or retain a reference to it that might later be used from another thread.”
Brian Goetz, Java Concurrency in Practice
“Once an object escapes, you have to assume that another class or thread may, maliciously or carelessly, misuse it. This is a compelling reason to use encapsulation: it makes it practical to analyze programs for correctness and harder to violate design constraints accidentally.”
Brian Goetz, Java Concurrency in Practice
“Accessing shared, mutable data requires using synchronization; one way to avoid this requirement is to not share. If data is only accessed from a single thread, no synchronization is needed. This technique, thread confinement, is one of the simplest ways to achieve thread safety. When an object is confined to a thread, such usage is automatically thread-safe even if the confined object itself is not.”
Brian Goetz, Java Concurrency in Practice
“Good uses of volatile variables include ensuring the visibility of their own state, that of the object they refer to, or indicating that an important lifecycle event (such as initialization or shutdown) has occurred.”
Brian Goetz, Java Concurrency in Practice
“immutability is not equivalent to simply declaring all fields of an object final. An object whose fields are all final may still be mutable, since final fields can hold references to mutable objects.”
Brian Goetz, Java Concurrency in Practice
“An object is immutable if: Its state cannot be modifled after construction; All its flelds are final;[12] and [12] It is technically possible to have an immutable object without all fields being final—String is such a class—but this relies on delicate reasoning about benign data races that requires a deep understanding of the Java Memory Model. (For the curious: String lazily computes the hash code the first time hashCode is called and caches it in a nonfinal field, but this works only because that field can take on only one nondefault value that is the same every time it is computed because it is derived deterministically from immutable state. Don't try this at home.) It is properly constructed (the this reference does not escape during construction).”
Brian Goetz, Java Concurrency in Practice
“To ensure thread safety, check-then-act operations (like lazy initialization) and read-modify-write operations (like increment) must always be atomic. We refer collectively to check-then-act and read-modify-write sequences as compound actions: sequences of operations that must be executed atomically in order to remain thread-safe.”
Brian Goetz, Java Concurrency in Practice
“The java.util.concurrent.atomic package contains atomic variable classes for effecting atomic state transitions on numbers and object references. By replacing the long counter with an AtomicLong, we ensure that all actions that access the counter state are atomic.”
Brian Goetz, Java Concurrency in Practice
“To preserve state consistency, update related state variables in a single atomic operation.”
Brian Goetz, Java Concurrency in Practice
“Acquiring the lock associated with an object does not prevent other threads from accessing that object—the only thing that acquiring a lock prevents any other thread from doing is acquiring that same lock. The fact that every object has a built-in lock is just a convenience so that you needn't explicitly create lock objects. [9] It is up to you to construct locking protocols or synchronization policies that let you access shared state safely, and to use them consistently throughout your program. [9]”
Brian Goetz, Java Concurrency in Practice
“Every shared, mutable variable should be guarded by exactly one lock. Make it clear to maintainers which lock that is.”
Brian Goetz, Java Concurrency in Practice
“Avoid holding locks during lengthy computations or operations at risk of not completing quickly such as network or console I/O.”
Brian Goetz, Java Concurrency in Practice
“it is a common misconception that synchronized is only about atomicity or demarcating “critical sections”. Synchronization also has another significant, and subtle, aspect: memory visibility. We want not only to prevent one thread from modifying the state of an object when another is using it, but also to ensure that when a thread modifies the state of an object, other threads can actually see the changes that were made.”
Brian Goetz, Java Concurrency in Practice
“When used properly, threads can reduce development and maintenance costs and improve the performance of complex applications.”
Brian Goetz, Java Concurrency in Practice
“When properly designed, multithreaded programs can improve throughput by utilizing available processor resources more effectively. Using multiple threads can also help achieve better throughput on singleprocessor systems. If a program is single-threaded, the processor remains idle while it waits for a synchronous I/O operation to complete. In a multithreaded program, another thread can still run while the first thread is waiting for the I/O to complete, allowing the application to still make progress during the blocking I/O. (This is like reading the newspaper while waiting for the water to boil, rather than waiting for the water to boil before starting to read.) 1.2.2.”
Brian Goetz, Java Concurrency in Practice
“in the absence of synchronization, the Java Memory Model permits the compiler to reorder operations and cache values in registers, and permits CPUs to reorder operations and cache values in processor-specific caches.”
Brian Goetz, Java Concurrency in Practice
“always use the proper synchronization whenever data is shared across threads. 3.1.1.”
Brian Goetz, Java Concurrency in Practice
“Stale data can cause serious and confusing failures such as unexpected exceptions, corrupted data structures, inaccurate computations, and infinite loops. [2]”
Brian Goetz, Java Concurrency in Practice
“The Java Memory Model requires fetch and store operations to be atomic, but for nonvolatile long and double variables, the JVM is permitted to treat a 64-bit read or write as two separate 32-bit operations. If the reads and writes occur in different threads, it is therefore possible to read a nonvolatile long and get back the high 32 bits of one value and the low 32 bits of another.[3] Thus, even if you don't care about stale values, it is not safe to use shared mutable long and double variables in multithreaded programs unless they are declared volatile or guarded by a lock. [3]”
Brian Goetz, Java Concurrency in Practice
“Because threads share the same memory address space and run concurrently, they can access or modify variables that other threads might be using. This is a tremendous convenience, because it makes data sharing much easier than would other inter-thread communications mechanisms. But it is also a significant risk: threads can be confused by having data change unexpectedly. Allowing multiple threads to access and modify the same variables introduces an element of nonsequentiality into an otherwise sequential programming model, which can be confusing and difficult to reason about. For a multithreaded program's behavior to be predictable, access to shared variables must be properly coordinated so that threads do not interfere with one another. Fortunately, Java provides synchronization mechanisms to coordinate such access. UnsafeSequence”
Brian Goetz, Java Concurrency in Practice

« previous 1 3