- Concurrent Patterns and Best Practices
- Atul S. Khot
- 496字
- 2021-07-16 17:32:31
Of patterns and paradigms
Moving away from explicit state management is a very prominent theme in programming. We always need a higher level of abstraction over the shared state model. As explained earlier, explicit locking does not cut it.
The various concurrency patterns that we will study in this book try to stay away from explicit locking. For example, immutability is a major theme, giving us persistent data structures. A persistent data structure performs a smart copy on a write, thereby avoiding mutation altogether, as shown in the following diagram:

As shown in the preceding diagram, the original linked list has three elements, {1, 2, 3}. The head element of the list has the value 1. Thread T1 starts counting the number of elements in the list.
At any point in time, thread T2 can prepend an element to the original list. This should not disturb the world of thread T1; it should still see the original list as it is. In other words, T1's version of the list as it sees it is preserved. Any change in the list creates a new version of the data structure. As all the versions live as long as they are needed (that is, are persistent), we don't need any locking.
Similarly, thread T2 removes the first two elements. This is achieved by just setting its head to the third element; again, this doesn't disturb the state as seen by T1 and T2.
This is essentially copy-on-write. Immutability is a cornerstone of functional programming languages.
A typical concurrency pattern is an active object. For example, how would you consume a legacy code base from multiple threads? The code base was written without any parallelism in mind, the state is strewn around, and it is almost impossible to figure out.
A brute-force approach could be to just wrap up the code in a big God object. Each thread could lock this object, use it, and relinquish the lock. However, this design would hurt concurrency, as it means that other threads would simply have to wait! Instead, we could use an active object, as shown in the following diagram:

To use this active object, a proxy sits in between the caller threads and the actual code base. It converts each invocation of the API into a runnable and puts it in a blocking queue (a thread-safe FIFO queue).
There is just one thread running in the God object. It executes the runnables on the queue one by one, in contrast to how a typical Java object method is invoked (passively). Here, the object itself executes the work placed on the queue, hence the term active object.
The rest of this chapter describes the many patterns and paradigms, that have evolved over the years, and are used in order to avoid the explicit locking of the shared state.
- Windows Server 2012 Hyper-V:Deploying the Hyper-V Enterprise Server Virtualization Platform
- Linux系統(tǒng)文件安全實(shí)戰(zhàn)全攻略
- Modern Web Testing with TestCafe
- 零起點(diǎn)學(xué)Linux系統(tǒng)管理
- Hands-On DevOps with Vagrant
- Windows Server 2012 Hyper-V Cookbook
- 高性能Linux服務(wù)器構(gòu)建實(shí)戰(zhàn):系統(tǒng)安全、故障排查、自動(dòng)化運(yùn)維與集群架構(gòu)
- RESS Essentials
- 完美應(yīng)用RHEL 8
- 一學(xué)就會(huì):Windows Vista應(yīng)用完全自學(xué)手冊
- Vim 8文本處理實(shí)戰(zhàn)
- Cassandra 3.x High Availability(Second Edition)
- 鴻蒙操作系統(tǒng)設(shè)計(jì)原理與架構(gòu)
- Windows 8玩全不求人
- Linux服務(wù)器配置與管理完全學(xué)習(xí)手冊