README-EN.md 13.9 KB
Newer Older
oldratlee's avatar
oldratlee 已提交
1
# 📌 Transmittable ThreadLocal(TTL) 📌
oldratlee's avatar
oldratlee 已提交
2

oldratlee's avatar
oldratlee 已提交
3
[![Build Status](https://travis-ci.org/alibaba/transmittable-thread-local.svg?branch=master)](https://travis-ci.org/alibaba/transmittable-thread-local)
4
[![Windows Build Status](https://img.shields.io/appveyor/ci/oldratlee/transmittable-thread-local/master.svg?label=windows%20build)](https://ci.appveyor.com/project/oldratlee/transmittable-thread-local)
oldratlee's avatar
oldratlee 已提交
5
[![Coverage Status](https://img.shields.io/codecov/c/github/alibaba/transmittable-thread-local/master.svg)](https://codecov.io/gh/alibaba/transmittable-thread-local/branch/master)
oldratlee's avatar
oldratlee 已提交
6 7
[![Maintainability](https://api.codeclimate.com/v1/badges/de6af6136e538cf1557c/maintainability)](https://codeclimate.com/github/alibaba/transmittable-thread-local/maintainability)  
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
oldratlee's avatar
oldratlee 已提交
8 9
[![Javadocs](https://img.shields.io/github/release/alibaba/transmittable-thread-local.svg?label=javadoc&color=3D9970)](https://alibaba.github.io/transmittable-thread-local/apidocs/)
[![Maven Central](https://img.shields.io/maven-central/v/com.alibaba/transmittable-thread-local.svg?color=6B5B95)](https://search.maven.org/search?q=g:com.alibaba%20AND%20a:transmittable-thread-local&core=gav)
oldratlee's avatar
oldratlee 已提交
10
[![GitHub release](https://img.shields.io/github/release/alibaba/transmittable-thread-local.svg)](https://github.com/alibaba/transmittable-thread-local/releases)  
oldratlee's avatar
oldratlee 已提交
11
[![Chat at gitter.im](https://badges.gitter.im/alibaba/transmittable-thread-local.svg)](https://gitter.im/alibaba/transmittable-thread-local?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
oldratlee's avatar
oldratlee 已提交
12 13
[![GitHub Stars](https://img.shields.io/github/stars/alibaba/transmittable-thread-local)](https://github.com/alibaba/transmittable-thread-local/stargazers)
[![GitHub Forks](https://img.shields.io/github/forks/alibaba/transmittable-thread-local)](https://github.com/alibaba/transmittable-thread-local/fork)
oldratlee's avatar
oldratlee 已提交
14
[![GitHub issues](https://img.shields.io/github/issues/alibaba/transmittable-thread-local.svg)](https://github.com/alibaba/transmittable-thread-local/issues)
oldratlee's avatar
oldratlee 已提交
15
[![Percentage of issues still open](http://isitmaintained.com/badge/open/alibaba/transmittable-thread-local.svg)](http://isitmaintained.com/project/alibaba/transmittable-thread-local "Percentage of issues still open")
oldratlee's avatar
oldratlee 已提交
16

oldratlee's avatar
oldratlee 已提交
17
📖 English Documentation | [📖 中文文档](README.md)
oldratlee's avatar
oldratlee 已提交
18

oldratlee's avatar
oldratlee 已提交
19 20 21 22 23 24
----------------------------------------

<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


oldratlee's avatar
oldratlee 已提交
25 26 27
- [🔧 Functions](#-functions)
- [🎨 Requirements](#-requirements)
- [👥 User Guide](#-user-guide)
oldratlee's avatar
oldratlee 已提交
28
    - [1. Simple usage](#1-simple-usage)
oldratlee's avatar
oldratlee 已提交
29 30 31
    - [2. Transmit value even using thread pool](#2-transmit-value-even-using-thread-pool)
        - [2.1 Decorate `Runnable` and `Callable`](#21-decorate-runnable-and-callable)
        - [2.2 Decorate thread pool](#22-decorate-thread-pool)
32
        - [2.3 Use Java Agent to decorate thread pool implementation class](#23-use-java-agent-to-decorate-thread-pool-implementation-class)
oldratlee's avatar
oldratlee 已提交
33
- [🔌 Java API Docs](#-java-api-docs)
oldratlee's avatar
oldratlee 已提交
34 35 36 37
- [🍪 Maven Dependency](#-maven-dependency)
- [🗿 More Documentation](#-more-documentation)
- [📚 Related Resources](#-related-resources)
    - [JDK Core Classes](#jdk-core-classes)
oldratlee's avatar
oldratlee 已提交
38
- [👷 Contributors](#-contributors)
oldratlee's avatar
oldratlee 已提交
39 40 41 42 43

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

----------------------------------------

oldratlee's avatar
oldratlee 已提交
44
# 🔧 Functions
oldratlee's avatar
oldratlee 已提交
45

oldratlee's avatar
oldratlee 已提交
46
👉 The missing Java™ std lib(simple & 0-dependency) for framework/middleware,
oldratlee's avatar
oldratlee 已提交
47
provide an enhanced `InheritableThreadLocal` that transmits `ThreadLocal` value between threads even using thread pooling components.
oldratlee's avatar
oldratlee 已提交
48
Support `Java` 13/12/11/10/9/8/7/6.
oldratlee's avatar
oldratlee 已提交
49

oldratlee's avatar
oldratlee 已提交
50
Class [`InheritableThreadLocal`](https://docs.oracle.com/javase/10/docs/api/java/lang/InheritableThreadLocal.html) in `JDK`
51
can transmit value to child thread from parent thread.
oldratlee's avatar
oldratlee 已提交
52

53 54
But when use thread pool, thread is cached up and used repeatedly. Transmitting value from parent thread to child thread has no meaning.
Application need transmit value from the time task is created to the time task is executed.
oldratlee's avatar
oldratlee 已提交
55

oldratlee's avatar
oldratlee 已提交
56
If you have problem or question, please [submit Issue](https://github.com/alibaba/transmittable-thread-local/issues) or play [fork](https://github.com/alibaba/transmittable-thread-local/fork) and pull request dance.
oldratlee's avatar
oldratlee 已提交
57

oldratlee's avatar
oldratlee 已提交
58
# 🎨 Requirements
oldratlee's avatar
oldratlee 已提交
59

oldratlee's avatar
oldratlee 已提交
60
The Requirements listed below is also why I sort out `TTL` in my work.
oldratlee's avatar
oldratlee 已提交
61

oldratlee's avatar
oldratlee 已提交
62 63
- Application container or high layer framework transmit information to low layer sdk.
- Transmit context to logging without application code aware.
oldratlee's avatar
oldratlee 已提交
64

oldratlee's avatar
oldratlee 已提交
65
# 👥 User Guide
oldratlee's avatar
oldratlee 已提交
66

oldratlee's avatar
oldratlee 已提交
67
## 1. Simple usage
oldratlee's avatar
oldratlee 已提交
68 69 70

```java
// set in parent thread
71
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
72 73 74 75 76
parent.set("value-set-in-parent");

// =====================================================

// read in child thread, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
77
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
78 79
```

oldratlee's avatar
oldratlee 已提交
80
This is the function of class [`InheritableThreadLocal`](https://docs.oracle.com/javase/10/docs/api/java/lang/InheritableThreadLocal.html), should use class [`InheritableThreadLocal`](https://docs.oracle.com/javase/10/docs/api/java/lang/InheritableThreadLocal.html) instead.
oldratlee's avatar
oldratlee 已提交
81

82 83
But when use thread pool, thread is cached up and used repeatedly. Transmitting value from parent thread to child thread has no meaning.
Application need transmit value from the time task is created to the point task is executed.
oldratlee's avatar
oldratlee 已提交
84 85 86

The solution is below usage.

oldratlee's avatar
oldratlee 已提交
87
## 2. Transmit value even using thread pool
oldratlee's avatar
oldratlee 已提交
88 89 90

### 2.1 Decorate `Runnable` and `Callable`

oldratlee's avatar
oldratlee 已提交
91 92
Decorate input `Runnable` and `Callable` by [`TtlRunnable`](/src/main/java/com/alibaba/ttl/TtlRunnable.java)
and [`TtlCallable`](src/main/java/com/alibaba/ttl/TtlCallable.java).
oldratlee's avatar
oldratlee 已提交
93 94 95 96

Sample code:

```java
97
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
98 99 100
parent.set("value-set-in-parent");

Runnable task = new Task("1");
101
// extra work, create decorated ttlRunnable object
oldratlee's avatar
oldratlee 已提交
102
Runnable ttlRunnable = TtlRunnable.get(task);
103
executorService.submit(ttlRunnable);
oldratlee's avatar
oldratlee 已提交
104 105 106 107

// =====================================================

// read in task, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
108
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
109 110 111 112 113
```

above code show how to dealing with `Runnable`, `Callable` is similar:

```java
114
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
115 116 117
parent.set("value-set-in-parent");

Callable call = new Call("1");
118
// extra work, create decorated ttlCallable object
oldratlee's avatar
oldratlee 已提交
119
Callable ttlCallable = TtlCallable.get(call);
120
executorService.submit(ttlCallable);
oldratlee's avatar
oldratlee 已提交
121 122 123 124

// =====================================================

// read in call, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
125
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
126 127 128 129 130 131 132
```

### 2.2 Decorate thread pool

Eliminating the work of `Runnable` and `Callable` Decoration every time it is submitted to thread pool. This work can completed in the thread pool.

Use util class
133
[`com.alibaba.ttl.threadpool.TtlExecutors`](src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java)
oldratlee's avatar
oldratlee 已提交
134 135
to decorate thread pool.

136
Util class `com.alibaba.ttl.threadpool.TtlExecutors` has below methods:
oldratlee's avatar
oldratlee 已提交
137

oldratlee's avatar
oldratlee 已提交
138 139 140
- `getTtlExecutor`: decorate interface `Executor`
- `getTtlExecutorService`: decorate interface `ExecutorService`
- `getTtlScheduledExecutorService`: decorate interface `ScheduledExecutorService`
oldratlee's avatar
oldratlee 已提交
141 142 143 144 145 146

Sample code:

```java
ExecutorService executorService = ...
// extra work, create decorated executorService object
oldratlee's avatar
oldratlee 已提交
147
executorService = TtlExecutors.getTtlExecutorService(executorService);
oldratlee's avatar
oldratlee 已提交
148

149
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
150 151 152 153 154 155 156 157 158 159
parent.set("value-set-in-parent");

Runnable task = new Task("1");
Callable call = new Call("2");
executorService.submit(task);
executorService.submit(call);

// =====================================================

// read in Task or Callable, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
160
String value = parent.get();
oldratlee's avatar
oldratlee 已提交
161 162
```

163
### 2.3 Use Java Agent to decorate thread pool implementation class
oldratlee's avatar
oldratlee 已提交
164

165
In this usage, transmission is transparent\(no decoration operation\).
oldratlee's avatar
oldratlee 已提交
166 167 168 169 170 171 172 173 174 175 176 177 178

Sample code:

```java
ExecutorService executorService = Executors.newFixedThreadPool(3);

Runnable task = new Task("1");
Callable call = new Call("2");
executorService.submit(task);
executorService.submit(call);

// =====================================================

oldratlee's avatar
oldratlee 已提交
179
// read in Task or Callable, value is "value-set-in-parent"
oldratlee's avatar
oldratlee 已提交
180 181 182
String value = parent.get();
```

183
See demo [`AgentDemo.kt`](src/test/java/com/alibaba/demo/agent/AgentDemo.kt).
oldratlee's avatar
oldratlee 已提交
184

oldratlee's avatar
oldratlee 已提交
185 186 187 188 189 190 191 192 193 194 195 196 197 198
At present, `TTL` agent has decorated below `JDK` execution components(aka. thread pool) implementation:

- `java.util.concurrent.ThreadPoolExecutor` and `java.util.concurrent.ScheduledThreadPoolExecutor`
    - decoration implementation code is in [`TtlExecutorTransformlet.java`](src/main/java/com/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlExecutorTransformlet.java).
- `java.util.concurrent.ForkJoinTask`(corresponding execution component is `java.util.concurrent.ForkJoinPool`
    - decoration implementation code is in [`TtlForkJoinTransformlet.java`](src/main/java/com/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlForkJoinTransformlet.java), supports since version **_`2.5.1`_**.
    - **_NOTE_**: [**_`CompletableFuture`_**](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/concurrent/CompletableFuture.html) and (parallel) [**_`Stream`_**](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/stream/package-summary.html) introduced in Java 8 is executed through `ForkJoinPool` underneath, so after supporting `ForkJoinPool`, `TTL` also supports `CompletableFuture` and `Stream` transparently. 🎉
- `java.util.TimerTask`(corresponding execution component is `java.util.Timer`
    - decoration implementation code is in [`TtlTimerTaskTransformlet.java`](src/main/java/com/alibaba/ttl/threadpool/agent/internal/transformlet/impl/TtlTimerTaskTransformlet.java), supports since version **_`2.7.0`_**.
    - **_NOTE_**: Since version `2.11.2` decoration for `TimerTask` default is enable (because correctness is first concern, not the best practice like "It is not recommended to use `TimerTask`" :); before version `2.11.1` default is disable.
    - enabled/disable by agent argument `ttl.agent.enable.timer.task`:
        - `-javaagent:path/to/transmittable-thread-local-2.x.x.jar=ttl.agent.enable.timer.task:true`
        - `-javaagent:path/to/transmittable-thread-local-2.x.x.jar=ttl.agent.enable.timer.task:false`
    - more info about `TTL` agent arguments, see [the javadoc of `TtlAgent.java`](src/main/java/com/alibaba/ttl/threadpool/agent/TtlAgent.java).
oldratlee's avatar
oldratlee 已提交
199

oldratlee's avatar
oldratlee 已提交
200
Add start options on Java command:
oldratlee's avatar
oldratlee 已提交
201

oldratlee's avatar
oldratlee 已提交
202
- `-javaagent:path/to/transmittable-thread-local-2.x.x.jar`
oldratlee's avatar
oldratlee 已提交
203

oldratlee's avatar
oldratlee 已提交
204
**NOTE**
oldratlee's avatar
oldratlee 已提交
205

oldratlee's avatar
oldratlee 已提交
206
- Because TTL agent modified the `JDK` std lib classes, make code refer from std lib class to the TTL classes, so the TTL Agent jar must be added to `boot classpath`.
oldratlee's avatar
oldratlee 已提交
207
- Since `v2.6.0`, TTL agent jar will auto add self to `boot classpath`. But you **should _NOT_** modify the downloaded TTL jar file name in the maven repo(eg: `transmittable-thread-local-2.x.x.jar`).
208 209
    - if you modified the downloaded TTL jar file name(eg: `ttl-foo-name-changed.jar`),
        you must add TTL agent jar to `boot classpath` manually by java option `-Xbootclasspath/a:path/to/ttl-foo-name-changed.jar`.
oldratlee's avatar
oldratlee 已提交
210

oldratlee's avatar
oldratlee 已提交
211
The implementation of auto adding self agent jar to `boot classpath` use the `Boot-Class-Path` property of manifest file(`META-INF/MANIFEST.MF`) in the TTL Java Agent Jar:
oldratlee's avatar
oldratlee 已提交
212

oldratlee's avatar
oldratlee 已提交
213 214
> `Boot-Class-Path`
>
oldratlee's avatar
oldratlee 已提交
215 216 217 218 219
> A list of paths to be searched by the bootstrap class loader. Paths represent directories or libraries (commonly referred to as JAR or zip libraries on many platforms).
> These paths are searched by the bootstrap class loader after the platform specific mechanisms of locating a class have failed. Paths are searched in the order listed.

More info:

oldratlee's avatar
oldratlee 已提交
220
- [`Java Agent Specification` - `JavaDoc`文档](https://docs.oracle.com/javase/10/docs/api/java/lang/instrument/package-summary.html#package.description)
oldratlee's avatar
oldratlee 已提交
221
- [JAR File Specification - JAR Manifest](https://docs.oracle.com/javase/10/docs/specs/jar/jar.html#jar-manifest)
oldratlee's avatar
oldratlee 已提交
222
- [Working with Manifest Files - The Java™ TutorialsHide](https://docs.oracle.com/javase/tutorial/deployment/jar/manifestindex.html)
oldratlee's avatar
oldratlee 已提交
223 224 225 226

Java command example:

```bash
oldratlee's avatar
oldratlee 已提交
227 228 229 230 231 232 233 234
java -javaagent:transmittable-thread-local-2.x.x.jar \
    -cp classes \
    com.alibaba.ttl.threadpool.agent.demo.AgentDemo
```

or

```bash
oldratlee's avatar
oldratlee 已提交
235 236
# if changed the TTL jar file name or the TTL version is before 2.6.0,
# should set argument -Xbootclasspath explicitly.
oldratlee's avatar
oldratlee 已提交
237 238
java -javaagent:path/to/ttl-foo-name-changed.jar \
    -Xbootclasspath/a:path/to/ttl-foo-name-changed.jar \
oldratlee's avatar
oldratlee 已提交
239
    -cp classes \
240
    com.alibaba.ttl.threadpool.agent.demo.AgentDemo
oldratlee's avatar
oldratlee 已提交
241 242
```

oldratlee's avatar
oldratlee 已提交
243
Run the script [`scripts/run-agent-demo.sh`](scripts/run-agent-demo.sh)
oldratlee's avatar
oldratlee 已提交
244 245
to start demo of "Use Java Agent to decorate thread pool implementation class".

oldratlee's avatar
oldratlee 已提交
246
# 🔌 Java API Docs
247

oldratlee's avatar
oldratlee 已提交
248
The current version Java API documentation: <https://alibaba.github.io/transmittable-thread-local/apidocs/>
249

oldratlee's avatar
oldratlee 已提交
250
# 🍪 Maven Dependency
oldratlee's avatar
oldratlee 已提交
251 252 253

```xml
<dependency>
oldratlee's avatar
oldratlee 已提交
254 255
    <groupId>com.alibaba</groupId>
    <artifactId>transmittable-thread-local</artifactId>
oldratlee's avatar
oldratlee 已提交
256
    <version>2.11.2</version>
oldratlee's avatar
oldratlee 已提交
257 258 259
</dependency>
```

260
Check available version at [search.maven.org](https://search.maven.org/search?q=g:com.alibaba%20AND%20a:transmittable-thread-local&core=gav).
oldratlee's avatar
oldratlee 已提交
261

oldratlee's avatar
oldratlee 已提交
262
# 🗿 More Documentation
oldratlee's avatar
oldratlee 已提交
263

oldratlee's avatar
oldratlee 已提交
264
- [🎓 Developer Guide](docs/developer-guide-en.md)
oldratlee's avatar
oldratlee 已提交
265

oldratlee's avatar
oldratlee 已提交
266
# 📚 Related Resources
oldratlee's avatar
oldratlee 已提交
267

oldratlee's avatar
oldratlee 已提交
268
## JDK Core Classes
oldratlee's avatar
oldratlee 已提交
269

oldratlee's avatar
oldratlee 已提交
270 271
- [WeakHashMap](https://docs.oracle.com/javase/10/docs/api/java/util/WeakHashMap.html)
- [InheritableThreadLocal](https://docs.oracle.com/javase/10/docs/api/java/lang/InheritableThreadLocal.html)
oldratlee's avatar
oldratlee 已提交
272

oldratlee's avatar
oldratlee 已提交
273 274 275 276
# 👷 Contributors

- Jerry Lee \<oldratlee at gmail dot com> [@oldratlee](https://github.com/oldratlee)
- Yang Fang \<snoop.fy at gmail dot com> [@driventokill](https://github.com/driventokill)
Z
Zava 已提交
277
- Zava Xu \<zava.kid at gmail dot com> [@zavakid](https://github.com/zavakid)
oldratlee's avatar
oldratlee 已提交
278
- wuwen \<wuwen.55 at aliyun dot com> [@wuwen5](https://github.com/wuwen5)
oldratlee's avatar
oldratlee 已提交
279
- Xiaowei Shi \<179969622 at qq dot com>  [@xwshiustc](https://github.com/xwshiustc)
oldratlee's avatar
oldratlee 已提交
280
- David Dai \<351450944 at qq dot com> [@LNAmp](https://github.com/LNAmp)
oldratlee's avatar
oldratlee 已提交
281
- Your name here :-)