Skip to content

Commit

Permalink
✏并发工具类
Browse files Browse the repository at this point in the history
  • Loading branch information
0xcaffebabe committed Aug 28, 2024
1 parent 3d6a322 commit 6c22e5b
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 1 deletion.
Binary file removed doc/assets/20202251401.jfif
Binary file not shown.
Binary file added doc/assets/20202251401.webp
Binary file not shown.
45 changes: 44 additions & 1 deletion doc/编程语言/JAVA/JAVA并发编程/并发工具类.md
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,49 @@ RequestContextHolder.getCurrentRquest();

解决上面这些问题只需要使用的时候注意remove即可

### InheritableThreadLocal

使用 InheritableThreadLocal,可以在子线程中获取到父线程中的 ThreadLocal 变量

其原理是子线程在初始化时,会去获取父线程的 ThreadLocalMap 来作为自己的 ThreadLocalMap

### TransmittableThreadLocal

在使用 TransmittableThreadLocal 时,它在将值保存到父类 InheritableThreadLocal 中的同时,会将当前的 TransmittableThreadLocal 实际进行存储,这样使用完成后,它自己就会维护一份所有用到的TransmittableThreadLocal 实例,不管它是用户信息的,还是其他信息的实例

有了上面维护的信息,就可以借助Transmitter来对其中的数据进行操作,一般操作步骤如下

- 主线程:调用Transmitter.capture,将当前主线程中的所有TransmittableThreadLocal和值进行快照保存(Map结构,结果要作为value进行存储,否则其他线程取不到TransmittableThreadLocal的value值)
- 子线程:调用Transmitter.replay,用于将之前保存的所有TransmittableThreadLocal实例及其值重新设置一下(需要借助之前保存的map结构,因为TransmittableThreadLocal中的数据是线程隔离的),并将当前线程的所有TransmittableThreadLocal实例进行备份返回
- 子线程:业务代码执行完毕之后调用Transmitter.restore,用于将之前备份的数据进行恢复,原理同replay方法

```mermaid
sequenceDiagram
participant Biz Code
participant Runnable
participant TtlRunnable
participant ThreadPool
participant TransmittableThreadLocal
participant Transmitter
Biz Code ->> TransmittableThreadLocal: createTtl()
Biz Code ->> TransmittableThreadLocal: setTtlValue()
Biz Code ->> Runnable: createBizTaskRunnable()
Biz Code ->> TtlRunnable: createTtlRunnableWrapper(Runnable)
TtlRunnable ->> Transmitter: captureAllTtlValues()
Transmitter ->> TransmittableThreadLocal: get()
Transmitter ->> TransmittableThreadLocal: copy(value:T)
Biz Code ->> ThreadPool: submitTtlRunnableToThreadPool()
ThreadPool ->> TtlRunnable: run()
TtlRunnable ->> TransmittableThreadLocal: beforeExecute()
TtlRunnable ->> Transmitter: replayCapturedTtlValues()
TtlRunnable ->> Runnable: run()
Runnable ->> TransmittableThreadLocal: useValueInTTL()
TtlRunnable ->> Transmitter: restoreTtlValuesBeforeReplay()
TtlRunnable ->> TransmittableThreadLocal: afterExecute()
```

## 锁的原理(AQS AbstractQueuedSynchronizer)

AQS 定义了一个volatile int state 作为共享变量 如果线程获取资源失败 就进入FIFO队列等待 成功后去资源就执行临界区代码 执行完释放资源 会通知同步队列中的等待线程来获取资源后出队执行
Expand All @@ -511,7 +554,7 @@ AQS 是一个锁框架,它定义了锁的实现机制,并开放出扩展的

### 整体架构

![20202251401](/assets/20202251401.jfif)
![20202251401](/assets/20202251401.webp)

- 提供了一种框架,自定义了先进先出的同步队列,让获取不到锁的线程能进入同步队列中排队
- 同步器有个状态字段,子类需要实现一些方法,通过判断状态字段来判断能否得到锁
Expand Down

0 comments on commit 6c22e5b

Please sign in to comment.