3BChapter 1-Introduction-12B1.3.Risks of Threads 》 In well designed concurrent applications the use of threads is a net performance gain,but threads nevertheless carry some degree of runtime overhead.Context switches-when the scheduler suspends the active thread temporarily so another thread can run-are more frequent in applications with many threads,and have significant costs:saving and restoring execution context,loss of locality,and CPU time spent scheduling threads instead of running them.When threads share data,they must use synchronization mechanisms that can inhibit compiler optimizations,flush or invalidate memory caches,and create synchronization traffic on the shared memory bus.All these factors introduce additional performance costs;Chapter 11 covers techniques for analyzing and reducing these costs
3BChapter 1Ͳ IntroductionͲ12B1.3. Risks of Threads 7 In well designed concurrent applications the use of threads is a net performance gain, but threads nevertheless carry some degree of runtime overhead. Context switches Ͳwhen the scheduler suspends the active thread temporarily so another thread can run Ͳare more frequent in applications with many threads, and have significant costs: saving and restoring execution context, loss of locality, and CPU time spent scheduling threads instead of running them. When threads share data, they must use synchronization mechanisms that can inhibit compiler optimizations, flush or invalidate memory caches, and create synchronization traffic on the shared memory bus. All these factors introduce additional performance costs; Chapter 11 covers techniques for analyzing and reducing these costs.
Java Concurrency In Practice 1.4.Threads are Everywhere Even if your program never explicitly creates a thread,frameworks may create threads on your behalf,and code called from these threads must be thread-safe.This can place a significant design and implementation burden on developers, since developing thread-safe classes requires more care and analysis than developing non-thread-safe classes. Every Java application uses threads.When the JVM starts,it creates threads for JVM housekeeping tasks (garbage collection,finalization)and a main thread for running the main method.The AWT (Abstract Window Toolkit)and Swing user interface frameworks create threads for managing user interface events.Timer creates threads for executing deferred tasks.Component frameworks,such as servlets and RMI create pools of threads and invoke component methods in these threads. If you use these facilities-as many developers do-you have to be familiar with concurrency and thread safety,because these frameworks create threads and call your components from them.It would be nice to believe that concurrency is an "optional"or "advanced"language feature,but the reality is that nearly all Java applications are multithreaded and these frameworks do not insulate you from the need to properly coordinate access to application state. When concurrency is introduced into an application by a framework,it is usually impossible to restrict the concurrency- awareness to the framework code,because frameworks by their nature make callbacks to application components that in turn access application state.Similarly,the need for thread safety does not end with the components called by the framework-it extends to all code paths that access the program state accessed by those components.Thus,the need for thread safety is contagious. Frameworks introduce concurrency into applications by calling application components from framework threads. Components invariably access application state,thus requiring that all code paths accessing that state be thread-safe. The facilities described below all cause application code to be called from threads not managed by the application. While the need for thread safety may start with these facilities,it rarely ends there;instead,it ripples through the application. Timer.Timer is a convenience mechanism for scheduling tasks to run at a later time,either once or periodically.The introduction of a Timer can complicate an otherwise sequential program,because TimerTasks are executed in a thread managed by the Timer,not the application.If a TimerTask accesses data that is also accessed by other application threads,then not only must the TimerTask do so in a thread-safe manner,but so must any other classes that access that data.Often the easiest way to achieve this is to ensure that objects accessed by the TimerTask are themselves thread-safe,thus encapsulating the thread safety within the shared objects. Servlets and JavaServer Pages (JSPs).The servlets framework is designed to handle all the infrastructure of deploying a web application and dispatching requests from remote HTTP clients.A request arriving at the server is dispatched, perhaps through a chain of filters,to the appropriate servlet or JSP.Each servlet represents a component of application logic,and in high-volume web sites,multiple clients may require the services of the same servlet at once.The servlets specification requires that a servlet be prepared to be called simultaneously from multiple threads.In other words, servlets need to be thread-safe. Even if you could guarantee that a servlet was only called from one thread at a time,you would still have to pay attention to thread safety when building a web application.Servlets often access state information shared with other servlets,such as application-scoped objects (those stored in the servletcontext)or session-scoped objects (those stored in the per-client Httpsession).When a servlet accesses objects shared across servlets or requests,it must coordinate access to these objects properly,since multiple requests could be accessing them simultaneously from separate threads.Servlets and JSPs,as well as servlet filters and objects stored in scoped containers like Servletcontext and Httpsession,simply have to be thread-safe. Remote Method Invocation.RMI lets you invoke methods on objects running in another JVM.When you call a remote method with RMI,the method arguments are packaged(marshaled)into a byte stream and shipped over the network to the remote JVM,where they are unpacked (unmarshaled)and passed to the remote method. When the RMI code calls your remote object,in what thread does that call happen?You don't know,but it's definitely not in a thread you created-your object gets called in a thread managed by RMI.How many threads does RMI create? Could the same remote method on the same remote object be called simultaneously in multiple RMI threads?4
8 Java Concurrency In Practice 1.4. Threads are Everywhere Even if your program never explicitly creates a thread, frameworks may create threads on your behalf, and code called from these threads must be threadͲsafe. This can place a significant design and implementation burden on developers, since developing threadͲsafe classes requires more care and analysis than developing nonͲthreadͲsafe classes. Every Java application uses threads. When the JVM starts, it creates threads for JVM housekeeping tasks (garbage collection, finalization) and a main thread for running the main method. The AWT (Abstract Window Toolkit) and Swing user interface frameworks create threads for managing user interface events. Timer creates threads for executing deferred tasks. Component frameworks, such as servlets and RMI create pools of threads and invoke component methods in these threads. If you use these facilitiesͲas many developers doͲyou have to be familiar with concurrency and thread safety, because these frameworks create threads and call your components from them. It would be nice to believe that concurrency is an "optional" or "advanced" language feature, but the reality is that nearly all Java applications are multithreaded and these frameworks do not insulate you from the need to properly coordinate access to application state. When concurrency is introduced into an application by a framework, it is usually impossible to restrict the concurrencyͲ awareness to the framework code, because frameworks by their nature make callbacks to application components that in turn access application state. Similarly, the need for thread safety does not end with the components called by the frameworkͲ it extends to all code paths that access the program state accessed by those components. Thus, the need for thread safety is contagious. Frameworks introduce concurrency into applications by calling application components from framework threads. Components invariably access application state, thus requiring that all code paths accessing that state be threadͲsafe. The facilities described below all cause application code to be called from threads not managed by the application. While the need for thread safety may start with these facilities, it rarely ends there; instead, it ripples through the application. Timer. Timer is a convenience mechanism for scheduling tasks to run at a later time, either once or periodically. The introduction of a Timer can complicate an otherwise sequential program, because TimerTasks are executed in a thread managed by the Timer, not the application. If a TimerTask accesses data that is also accessed by other application threads, then not only must the TimerTask do so in a threadͲsafe manner, but so must any other classes that access that data. Often the easiest way to achieve this is to ensure that objects accessed by the TimerTask are themselves threadͲsafe, thus encapsulating the thread safety within the shared objects. Servlets and JavaServer Pages (JSPs). The servlets framework is designed to handle all the infrastructure of deploying a web application and dispatching requests from remote HTTP clients. A request arriving at the server is dispatched, perhaps through a chain of filters, to the appropriate servlet or JSP. Each servlet represents a component of application logic, and in highͲvolume web sites, multiple clients may require the services of the same servlet at once. The servlets specification requires that a servlet be prepared to be called simultaneously from multiple threads. In other words, servlets need to be threadͲsafe. Even if you could guarantee that a servlet was only called from one thread at a time, you would still have to pay attention to thread safety when building a web application. Servlets often access state information shared with other servlets, such as applicationͲscoped objects (those stored in the ServletContext) or sessionͲscoped objects (those stored in the perͲclient HttpSession). When a servlet accesses objects shared across servlets or requests, it must coordinate access to these objects properly, since multiple requests could be accessing them simultaneously from separate threads. Servlets and JSPs, as well as servlet filters and objects stored in scoped containers like ServletContext and HttpSession, simply have to be threadͲsafe. Remote Method Invocation. RMI lets you invoke methods on objects running in another JVM. When you call a remote method with RMI, the method arguments are packaged (marshaled) into a byte stream and shipped over the network to the remote JVM, where they are unpacked (unmarshaled) and passed to the remote method. When the RMI code calls your remote object, in what thread does that call happen? You don't know, but it's definitely not in a thread you createdͲyour object gets called in a thread managed by RMI. How many threads does RMI create? Could the same remote method on the same remote object be called simultaneously in multiple RMI threads?[4]
3BChapter 1-Introduction-13B1.4.Threads are Everywhere 9 [4]Answer:yes,but it's not all that clear from the Javadoc-you have to read the RMI spec. A remote object must guard against two thread safety hazards:properly coordinating access to state that may be shared with other objects,and properly coordinating access to the state of the remote object itself(since the same object may be called in multiple threads simultaneously).Like servlets,RMI objects should be prepared for multiple simultaneous calls and must provide their own thread safety. Swing and AWT.GUl applications are inherently asynchronous.Users may select a menu item or press a button at any time,and they expect that the application will respond promptly even if it is in the middle of doing something else. Swing and AWT address this problem by creating a separate thread for handling user-initiated events and updating the graphical view presented to the user. Swing components,such as JTable,are not thread-safe.Instead,Swing programs achieve their thread safety by confining all access to GUl components to the event thread.If an application wants to manipulate the GUl from outside the event thread,it must cause the code that will manipulate the GUl to run in the event thread instead. When the user performs a Ul action,an event handler is called in the event thread to perform whatever operation the user requested.If the handler needs to access application state that is also accessed from other threads (such as a document being edited),then the event handler,along with any other code that accesses that state,must do so in a thread-safe manner
3BChapter 1Ͳ Introduction Ͳ 13B1.4. Threads are Everywhere 9 [4] Answer: yes, but it's not all that clear from the JavadocͲyou have to read the RMI spec. A remote object must guard against two thread safety hazards: properly coordinating access to state that may be shared with other objects, and properly coordinating access to the state of the remote object itself (since the same object may be called in multiple threads simultaneously). Like servlets, RMI objects should be prepared for multiple simultaneous calls and must provide their own thread safety. Swing and AWT. GUI applications are inherently asynchronous. Users may select a menu item or press a button at any time, and they expect that the application will respond promptly even if it is in the middle of doing something else. Swing and AWT address this problem by creating a separate thread for handling userͲinitiated events and updating the graphical view presented to the user. Swing components, such as JTable, are not threadͲsafe. Instead, Swing programs achieve their thread safety by confining all access to GUI components to the event thread. If an application wants to manipulate the GUI from outside the event thread, it must cause the code that will manipulate the GUI to run in the event thread instead. When the user performs a UI action, an event handler is called in the event thread to perform whatever operation the user requested. If the handler needs to access application state that is also accessed from other threads (such as a document being edited), then the event handler, along with any other code that accesses that state, must do so in a threadͲsafe manner.
10 Java Concurrency In Practice Part I:Fundamentals Chapter 2.Thread Safety Chapter 3.Sharing Objects Chapter 4.Composing Objects Chapter 5.Building Blocks
10 Java Concurrency In Practice Part I: Fundamentals Chapter 2.Thread Safety Chapter 3.Sharing Objects Chapter 4.Composing Objects Chapter 5.Building Blocks
5288B5287B5286B5249B5230B5229B5200B5148B4916B4722B4721B4720B4719B4594B4593B4569B4568B4567B45 66B4565B4564B4427B4426B4410B4409B4345B4218B4217B4216B4215B3636B3635B3469B3468B3465B3455B3454 11 B3453B3449B3221B3220B3219B3214B3059B3058B3057B2535B2534B2190B2189B2188B2-14 BChapter2.Thread Safety Chapter 2.Thread Safety Perhaps surprisingly,concurrent programming isn't so much about threads or locks,any more than civil engineering is about rivets and I-beams.Of course,building bridges that don't fall down requires the correct use of a lot of rivets and I- beams,just as building concurrent programs require the correct use of threads and locks.But these are just mechanisms means to an end.Writing thread-safe code is,at its core,about managing access to state,and in particular to shared, mutable state. Informally,an object's state is its data,stored in state variables such as instance or static fields.An object's state may include fields from other,dependent objects;a HashMap's state is partially stored in the HashMap object itself,but also in many Map.Entry objects.An object's state encompasses any data that can affect its externally visible behavior. By shared,we mean that a variable could be accessed by multiple threads;by mutable,we mean that its value could change during its lifetime.We may talk about thread safety as if it were about code,but what we are really trying to do is protect data from uncontrolled concurrent access. Whether an object needs to be thread-safe depends on whether it will be accessed from multiple threads.This is a property of how the object is used in a program,not what it does.Making an object thread-safe requires using synchronization to coordinate access to its mutable state;failing to do so could result in data corruption and other undesirable consequences. 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.The primary mechanism for synchronization in Java is the synchronized keyword,which provides exclusive locking,but the term "synchronization"also includes the use of volatile variables,explicit locks,and atomic variables. You should avoid the temptation to think that there are "special"situations in which this rule does not apply.A program that omits needed synchronization might appear to work,passing its tests and performing well for years,but it is still broken and may fail at any moment. If multiple threads access the same mutable state variable without appropriate synchronization,your program is broken.There are three ways to fix it: ● Don't share the state variable across threads; Make the state variable immutable;or Use synchronization whenever accessing the state variable. If you haven't considered concurrent access in your class design,some of these approaches can require significant design modifications,so fixing the problem might not be as trivial as this advice makes it sound.It is far easier to design a class to be thread-safe than to retrofit it for thread safety later. In a large program,identifying whether multiple threads might access a given variable can be complicated.Fortunately, the same object-oriented techniques that help you write well-organized,maintainable classes-such as encapsulation and data hiding-can also help you create thread-safe classes.The less code that has access to a particular variable,the easier it is to ensure that all of it uses the proper synchronization,and the easier it is to reason about the conditions under which a given variable might be accessed.The Java language doesn't force you to encapsulate state it is perfectly allowable to store state in public fields (even public static fields)or publish a reference to an otherwise internal object-but the better encapsulated your program state,the easier it is to make your program thread-safe and to help maintainers keep it that way. When designing thread-safe classes,good object-oriented techniques encapsulation,immutability,and clear specification of invariants-are your best friends. There will be times when good object-oriented design techniques are at odds with real-world requirements;it may be necessary in these cases to compromise the rules of good design for the sake of performance or for the sake of backward compatibility with legacy code.Sometimes abstraction and encapsulation are at odds with performance-
11 5288B5287B5286B5249B5230B5229B5200B5148B4916B4722B4721B4720B4719B4594B4593B4569B4568B4567B45 66B4565B4564B4427B4426B4410B4409B4345B4218B4217B4216B4215B3636B3635B3469B3468B3465B3455B3454 B3453B3449B3221B3220B3219B3214B3059B3058B3057B2535B2534B2190B2189B2188B2Ͳ14BChapter 2. Thread Safety Chapter 2. Thread Safety Perhaps surprisingly, concurrent programming isn't so much about threads or locks, any more than civil engineering is about rivets and IͲbeams. Of course, building bridges that don't fall down requires the correct use of a lot of rivets and IͲ beams, just as building concurrent programs require the correct use of threads and locks. But these are just mechanisms means to an end. Writing threadͲsafe code is, at its core, about managing access to state, and in particular to shared, mutable state. Informally, an object's state is its data, stored in state variables such as instance or static fields. An object's state may include fields from other, dependent objects; a HashMap's state is partially stored in the HashMap object itself, but also in many Map.Entry objects. An object's state encompasses any data that can affect its externally visible behavior. By shared, we mean that a variable could be accessed by multiple threads; by mutable, we mean that its value could change during its lifetime. We may talk about thread safety as if it were about code, but what we are really trying to do is protect data from uncontrolled concurrent access. Whether an object needs to be threadͲsafe depends on whether it will be accessed from multiple threads. This is a property of how the object is used in a program, not what it does. Making an object threadͲsafe requires using synchronization to coordinate access to its mutable state; failing to do so could result in data corruption and other undesirable consequences. 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. The primary mechanism for synchronization in Java is the synchronized keyword, which provides exclusive locking, but the term "synchronization" also includes the use of volatile variables, explicit locks, and atomic variables. You should avoid the temptation to think that there are "special" situations in which this rule does not apply. A program that omits needed synchronization might appear to work, passing its tests and performing well for years, but it is still broken and may fail at any moment. If multiple threads access the same mutable state variable without appropriate synchronization, your program is broken. There are three ways to fix it: x Don't share the state variable across threads; x Make the state variable immutable; or x Use synchronization whenever accessing the state variable. If you haven't considered concurrent access in your class design, some of these approaches can require significant design modifications, so fixing the problem might not be as trivial as this advice makes it sound. It is far easier to design a class to be threadͲsafe than to retrofit it for thread safety later. In a large program, identifying whether multiple threads might access a given variable can be complicated. Fortunately, the same objectͲoriented techniques that help you write wellͲorganized, maintainable classes Ͳsuch as encapsulation and data hidingͲcan also help you create threadͲsafe classes. The less code that has access to a particular variable, the easier it is to ensure that all of it uses the proper synchronization, and the easier it is to reason about the conditions under which a given variable might be accessed. The Java language doesn't force you to encapsulate state Ͳ it is perfectly allowable to store state in public fields (even public static fields) or publish a reference to an otherwise internal objectͲbut the better encapsulated your program state, the easier it is to make your program threadͲsafe and to help maintainers keep it that way. When designing threadͲsafe classes, good objectͲoriented techniques Ͳ encapsulation, immutability, and clear specification of invariantsͲare your best friends. There will be times when good objectͲoriented design techniques are at odds with realͲworld requirements; it may be necessary in these cases to compromise the rules of good design for the sake of performance or for the sake of backward compatibility with legacy code. Sometimes abstraction and encapsulation are at odds with performance Ͳ