19 Apr 2021
Chanpter 11 : Serialization
You can find the longer version of this summary here.
Serialization
- Use
JSON, protocol buffer instead of Java serialization.
JSON is human-readable.
- Because the
protocol buffer is a binary representation, it is highly efficient.
Prohibit use of Serializable
Serailzable is vulnerable to security
- Prohibit
Serailzable in classes designed for inheritance and interfaces.
- Inner classes should not implement serialization.
- If not for inheritance, use serialization proxy pattern
- Create nested class
- Implement Outer class
writeReplace() + readObject()
- Implement Nested class
readResolve()
If you’re still going to use Seralizable,
- Judgment of logical and physical differences.
- Logic == physics
- Just implement
Serailzable
- Logic != Physics
- Custom serialization
transient + writeObject() + readObject()
- UID explicitly granted (compatibility)
- When writing
readObejct() (like public constructor)
- Defensive copy
- Prohibit calling overridable methods
- Instance control class
Enum type for singleton class
- If the
enum type is not available, readResolve() + transient
12 Apr 2021
Chanpter 10 : Concurrency
You can find the longer version of this summary here.
Concurrency satisfaction
- Exclusive execution:
synchronized keyword
- Communication between threads:
volatile field, both read and write sychronization
Synchronization failure
- Unresponsive, safety failure
- Avoid calling alien methods
- Minimize the synchronization area
Executor rather than thread, use task, use concurrency utility
- Normally use
newCachedThreadPool
- Use
newFixedThreadPool on heavy servers
- If you want full control, use
ThreadPoolExecutor class directly
ConcurrentHashMap, BlockingQueue, CountDownLatch, Semaphore, Phaser
Documentation
- Immutable: No need to sync (
@Immutable)
- Unconditional thread safety: No need to sync (
@ThreadSafe)
- Conditional thread safety: synchronization for some methods (
@ThreadSafe)
- Not thread safe: should be wrapped with an external synchronization mechanism (
@NotThreadSafe)
Caution
- Avoid using lazy initialization (
synchroized, volatile)
- Avoid priority for
Thread (using Thread.yield)
05 Apr 2021
Item 66: Use native methods judiciously
- It is rarely advisable to use native methods for improved performance. In early releases (prior to Java 3), it was often necessary, but JVMs have gotten much faster since then.
- Disadvantages: native methods are not safe, less portable, harder to debug, may leak memory.
Item 67: Optimize judiciously
Premature optimization is the root of all evil.
We follow two rules in the matter of optimization:
Rule 1. Don’t do it.
Rule 2 (for experts only). Don’t do it yet—that is, not until you have a perfectly clear and unoptimized solution.
- Strive to write good programs rather than fast ones.
- Strive to avoid design decisions that limit performance.
- It is a very bad idea to warp an API to achieve good performance.
Item 68: Adhere to generally accepted naming conventions
Item 69: Use exceptions only for exceptional conditions
- Don’t use it for control flows.
- A well-designed API must not force its clients to use exceptions for ordinary control flow.
Item 70: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
- Throw checked exceptions for recoverable conditions and unchecked exceptions for programming errors.
Item 71: Avoid unnecessary use of checked exceptions
- If callers won’t be able to recover from failures, throw unchecked exceptions. If recovery may be possible and you want to force callers to handle exceptional conditions, first consider returning an optional. Only if this would provide insufficient information in the case of failure should you throw a checked exception.
Item 72: Favor the use of standard exceptions
- such as IllegalArgumentException, IllegalStateException, NullPointerException.
Item 73: Throw exceptions appropriate to the abstraction
- If it isn’t feasible to prevent or to handle exceptions from lower layers, use exception translation, unless the lower-level method happens to guarantee that all of its exceptions are appropriate to the higher level. Chaining provides the best of both worlds: it allows you to throw an appropriate higher-level exception, while capturing the underlying cause for failure analysis.
Item 74: Document all exceptions thrown by each method
- document every exception that can be thrown by each method that you write. Use
throws clause and @throws tag.