JCIP-4-Composing Objects

7 篇文章 0 订阅

4-Composing Objects
4.1-Designing a Thread-safe Class
4.1.1. Gathering Synchronization Requirements
The design process for a threadͲsafe class should include these three basic elements:
x Identify the variables that form the object’s state;
x Identify the invariants that constrain the state variables;
x Establish a policy for managing concurrent access to the object’s state.
The synchronization policy defines how an object coordinates access to its state without violating its invariants or postͲ
conditions.
You cannot ensure thread safety without understanding an object’s invariants and post-conditions. Constraints on the
valid values or state transitions for state variables can create atomicity and encapsulation requirements.
4.1.2. State-dependent Operations
The built-in mechanisms for efficiently waiting for a condition to become true -wait and notify -are tightly bound to
intrinsic locking, and can be difficult to use correctly.
4.1.3. State Ownership
but once you publish a reference to a mutable object, you
no longer have exclusive control; at best, you might have “shared ownership”
“split ownership”:These objects are owned by the application; they are being stored for safekeeping by the servlet container on the application’s behalf.
4.2-Instance Confinement
start
Encapsulating data within an object confines access to the data to the object’s methods, making it easier to ensure that
the data is always accessed with the appropriate lock held.
Instance confinement also allows different state variables to be guarded by different locks.
Decorator pattern to wrap the collection with a synchronized wrapper object; the wrapper implements each method of the appropriate interface as a synchronized method that forwards the request to the underlying collection object. So long as the
wrapper object holds the only reachable reference to the underlying collection .the
underlying collection must be made through the wrapper.
Confinement makes it easier to build thread-safe classes because a class that confines its state can be analyzed for
thread safety without having to examine the whole program.
4.2.1. The Java Monitor Pattern
encapsulates all its mutable state and guards it with the object’s own intrinsic
lock.
The Java monitor pattern is used by many library classes, such as Vector and Hashtable.
There are advantages to using a private lock object instead of an object’s intrinsic lock (or any other publicly accessible
lock). Making the lock object private encapsulates the lock so that client code cannot acquire it
4.2.2. Example: Tracking Fleet Vehicles
deepCopy can’t just wrap the Map with an unmodifiableMap, because that protects only the collection from modification; it does not
prevent callers from modifying the mutable objects stored in it.
4.3-Delegating Thread Safety
start
The Java monitor pattern is useful when building classes from
scratch or composing classes out of objects that are not thread-safe.
4.3.1. Example: Vehicle Tracker Using Delegation
4.3.2. Independent State Variables
4.3.3. When Delegation Fails
If a class is composed of multiple independent thread-safe state variables and has no operations that have any invalid
state transitions, then it can delegate thread safety to the underlying state variables.
4.3.4. Publishing Underlying State Variables
If a state variable is thread-safe, does not participate in any invariants that constrain its value, and has no prohibited
state transitions for any of its operations, then it can safely be published.
4.3.5. Example: Vehicle Tracker that Publishes Its State
4.4-Adding Functionality to Existing Thread-safe Classes
start
reuse can reduce development effort, development risk and maintenance cost
you need to understand the implementation’s synchronization policy so that you can enhance
it in a manner consistent with its original design
Extension is more fragile than adding code directly to a class ,change its
synchronization policy by choosing a different lock to guard its state variables,no longer used the right lock to control concurrent access to the base class’s state.
4.4.1. Client-side Locking
To make this approach work, we have to use the same lock that the List uses by using client-side locking or external
locking.
client-side
locking violates encapsulation of synchronization policy.
4.4.2. Composition
There is a less fragile alternative for adding an atomic operation to an existing class: composition.
assumes that once a list is passed to its constructor, the client will not use the underlying list directly again, accessing it only
through the ImprovedList.
4.5-Documenting Synchronization Policies
start
Document a class’s thread safety guarantees for its clients; document its synchronization policy for its maintainers.
java.text.SimpleDateFormat isn’t threadͲsafe, but the Javadoc neglected to mention this until
JDK 1.4.
Don’t make your customers or
colleagues have to make guesses like this.
4.5.1. Interpreting Vague Documentation
So the servlet container should expect to have
these objects accessed concurrently, since it has created multiple threads and called methods like Servlet.service
from them
has to assume
that they have been made thread-safe, even though the specification does not explicitly
even though the specification doesn’t promise that DataSource is
thread-safe or require container vendors to provide a thread-safe implementation, by the same “it would be absurd if it
weren’t” argument, we have no choice but to assume that DataSource.getConnection does not require additional
client-side locking.
4.1-Designing a Thread-safe Class
4.1.1. Gathering Synchronization Requirements
The design process for a threadͲsafe class should include these three basic elements:
x Identify the variables that form the object’s state;
x Identify the invariants that constrain the state variables;
x Establish a policy for managing concurrent access to the object’s state.
The synchronization policy defines how an object coordinates access to its state without violating its invariants or postͲ
conditions.
You cannot ensure thread safety without understanding an object’s invariants and post-conditions. Constraints on the
valid values or state transitions for state variables can create atomicity and encapsulation requirements.
4.1.2. State-dependent Operations
The built-in mechanisms for efficiently waiting for a condition to become true -wait and notify -are tightly bound to
intrinsic locking, and can be difficult to use correctly.
4.1.3. State Ownership
but once you publish a reference to a mutable object, you
no longer have exclusive control; at best, you might have “shared ownership”
“split ownership”:These objects are owned by the application; they are being stored for safekeeping by the servlet container on the application’s behalf.
4.2-Instance Confinement
start
Encapsulating data within an object confines access to the data to the object’s methods, making it easier to ensure that
the data is always accessed with the appropriate lock held.
Instance confinement also allows different state variables to be guarded by different locks.
Decorator pattern to wrap the collection with a synchronized wrapper object; the wrapper implements each method of the appropriate interface as a synchronized method that forwards the request to the underlying collection object. So long as the
wrapper object holds the only reachable reference to the underlying collection .the
underlying collection must be made through the wrapper.
Confinement makes it easier to build thread-safe classes because a class that confines its state can be analyzed for
thread safety without having to examine the whole program.
4.2.1. The Java Monitor Pattern
encapsulates all its mutable state and guards it with the object’s own intrinsic
lock.
The Java monitor pattern is used by many library classes, such as Vector and Hashtable.
There are advantages to using a private lock object instead of an object’s intrinsic lock (or any other publicly accessible
lock). Making the lock object private encapsulates the lock so that client code cannot acquire it
4.2.2. Example: Tracking Fleet Vehicles
deepCopy can’t just wrap the Map with an unmodifiableMap, because that protects only the collection from modification; it does not
prevent callers from modifying the mutable objects stored in it.
4.3-Delegating Thread Safety
start
The Java monitor pattern is useful when building classes from
scratch or composing classes out of objects that are not thread-safe.
4.3.1. Example: Vehicle Tracker Using Delegation
4.3.2. Independent State Variables
4.3.3. When Delegation Fails
If a class is composed of multiple independent thread-safe state variables and has no operations that have any invalid
state transitions, then it can delegate thread safety to the underlying state variables.
4.3.4. Publishing Underlying State Variables
If a state variable is thread-safe, does not participate in any invariants that constrain its value, and has no prohibited
state transitions for any of its operations, then it can safely be published.
4.3.5. Example: Vehicle Tracker that Publishes Its State
4.4-Adding Functionality to Existing Thread-safe Classes
start
reuse can reduce development effort, development risk and maintenance cost
you need to understand the implementation’s synchronization policy so that you can enhance
it in a manner consistent with its original design
Extension is more fragile than adding code directly to a class ,change its
synchronization policy by choosing a different lock to guard its state variables,no longer used the right lock to control concurrent access to the base class’s state.
4.4.1. Client-side Locking
To make this approach work, we have to use the same lock that the List uses by using client-side locking or external
locking.
client-side
locking violates encapsulation of synchronization policy.
4.4.2. Composition
There is a less fragile alternative for adding an atomic operation to an existing class: composition.
assumes that once a list is passed to its constructor, the client will not use the underlying list directly again, accessing it only
through the ImprovedList.
4.5-Documenting Synchronization Policies
start
Document a class’s thread safety guarantees for its clients; document its synchronization policy for its maintainers.
java.text.SimpleDateFormat isn’t threadͲsafe, but the Javadoc neglected to mention this until
JDK 1.4.
Don’t make your customers or
colleagues have to make guesses like this.
4.5.1. Interpreting Vague Documentation
So the servlet container should expect to have
these objects accessed concurrently, since it has created multiple threads and called methods like Servlet.service
from them
has to assume
that they have been made thread-safe, even though the specification does not explicitly
even though the specification doesn’t promise that DataSource is
thread-safe or require container vendors to provide a thread-safe implementation, by the same “it would be absurd if it
weren’t” argument, we have no choice but to assume that DataSource.getConnection does not require additional
client-side locking.

DISSIDIA思维导图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值