README-EN.md 9.0 KB
Newer Older
1
Transmittable ThreadLocal(TTL)
oldratlee's avatar
oldratlee 已提交
2 3
=====================================

oldratlee's avatar
oldratlee 已提交
4
[![Build Status](https://travis-ci.org/alibaba/transmittable-thread-local.svg?branch=master)](https://travis-ci.org/alibaba/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
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.alibaba/transmittable-thread-local/badge.svg)](https://maven-badges.herokuapp.com/maven-central/com.alibaba/transmittable-thread-local/)
[![GitHub release](https://img.shields.io/github/release/alibaba/transmittable-thread-local.svg)](https://github.com/alibaba/transmittable-thread-local/releases)  
T
The Gitter Badger 已提交
8
[![Join the chat at https://gitter.im/alibaba/transmittable-thread-local](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 已提交
9
[![GitHub issues](https://img.shields.io/github/issues/alibaba/transmittable-thread-local.svg)](https://github.com/alibaba/transmittable-thread-local/issues)
T
The Gitter Badger 已提交
10
[![Dependency Status](https://www.versioneye.com/user/projects/56c0a36218b271002c699dca/badge.svg)](https://www.versioneye.com/user/projects/56c0a36218b271002c699dca)
oldratlee's avatar
oldratlee 已提交
11
[![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html)
oldratlee's avatar
oldratlee 已提交
12

oldratlee's avatar
oldratlee 已提交
13
<div align="right">
oldratlee's avatar
oldratlee 已提交
14
<a href="README.md">中文文档</a>
oldratlee's avatar
oldratlee 已提交
15 16
</div>

oldratlee's avatar
oldratlee 已提交
17 18 19
:wrench: Functions
----------------------------

20
:point_right: Transmit `ThreadLocal` value between threads, even using thread cached components like thread pool.
oldratlee's avatar
oldratlee 已提交
21

22
Class [`InheritableThreadLocal`](http://docs.oracle.com/javase/7/docs/api/java/lang/InheritableThreadLocal.html) in `JDK`
23
can transmit value to child thread from parent thread.
oldratlee's avatar
oldratlee 已提交
24

25 26
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 已提交
27

oldratlee's avatar
oldratlee 已提交
28
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 已提交
29

oldratlee's avatar
oldratlee 已提交
30
:art: Requirements
oldratlee's avatar
oldratlee 已提交
31 32
----------------------------

33
The Requirements listed below is also why I sort out `TTL` in my work. 
oldratlee's avatar
oldratlee 已提交
34 35 36 37

* Application container or high layer framework transmit information to low layer sdk.
* Transmit context to logging without application code aware.

oldratlee's avatar
oldratlee 已提交
38
:busts_in_silhouette: User Guide
oldratlee's avatar
oldratlee 已提交
39 40 41 42 43 44 45
=====================================

1. simple usage
----------------------------

```java
// set in parent thread
46
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
47 48 49 50 51 52 53 54
parent.set("value-set-in-parent");

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

// read in child thread, value is "value-set-in-parent"
String value = parent.get(); 
```

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

57 58
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 已提交
59 60 61

The solution is below usage.

62
2. Transmit value even using thread pool
oldratlee's avatar
oldratlee 已提交
63 64 65 66
----------------------------

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

67 68
Decorate input `Runnable` and `Callable` by [`com.alibaba.ttl.TtlRunnable`](/src/main/java/com/alibaba/ttl/TtlRunnable.java)
and [`com.alibaba.ttl.TtlCallable`](src/main/java/com/alibaba/ttl/TtlCallable.java).
oldratlee's avatar
oldratlee 已提交
69 70 71 72

Sample code:

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

Runnable task = new Task("1");
77 78 79
// extra work, create decorated ttlRunnable object
Runnable ttlRunnable = TtlRunnable.get(task); 
executorService.submit(ttlRunnable);
oldratlee's avatar
oldratlee 已提交
80 81 82 83 84 85 86 87 88 89

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

// read in task, value is "value-set-in-parent"
String value = parent.get(); 
```

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

```java
90
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
91 92 93
parent.set("value-set-in-parent");

Callable call = new Call("1");
94 95 96
// extra work, create decorated ttlCallable object
Callable ttlCallable = TtlCallable.get(call); 
executorService.submit(ttlCallable);
oldratlee's avatar
oldratlee 已提交
97 98 99 100 101 102 103 104 105 106 107 108

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

// read in call, value is "value-set-in-parent"
String value = parent.get(); 
```

### 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
109
[`com.alibaba.ttl.threadpool.TtlExecutors`](src/main/java/com/alibaba/ttl/threadpool/TtlExecutors.java)
oldratlee's avatar
oldratlee 已提交
110 111
to decorate thread pool.

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

114 115
* `getTtlExecutor`: decorate interface `Executor`
* `getTtlExecutorService`: decorate interface `ExecutorService`
oldratlee's avatar
oldratlee 已提交
116 117 118 119 120 121 122
* `ScheduledExecutorService`: decorate interface `ScheduledExecutorService`

Sample code:

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

125
TransmittableThreadLocal<String> parent = new TransmittableThreadLocal<String>();
oldratlee's avatar
oldratlee 已提交
126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
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"
String value = parent.get(); 
```

### 2.3. Use Java Agent to decorate thread pool implementation class

141
In this usage, transmission is transparent\(no decoration operation\).
oldratlee's avatar
oldratlee 已提交
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158

Sample code:

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

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

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

// Task或是Call中可以读取, 值是"value-set-in-parent"
String value = parent.get();
```

159
See demo [`AgentDemo.java`](src/test/java/com/alibaba/ttl/threadpool/agent/AgentDemo.java).
oldratlee's avatar
oldratlee 已提交
160 161

Agent decorate 2 thread pool implementation classes
162
\(implementation code [`TtlTransformer.java`](src/main/java/com/alibaba/ttl/threadpool/agent/TtlTransformer.java)\):
oldratlee's avatar
oldratlee 已提交
163 164 165 166

- `java.util.concurrent.ThreadPoolExecutor`
- `java.util.concurrent.ScheduledThreadPoolExecutor`

oldratlee's avatar
oldratlee 已提交
167
Add start options on Java command: 
oldratlee's avatar
oldratlee 已提交
168

169 170
- `-Xbootclasspath/a:/path/to/transmittable-thread-local-2.x.x.jar`
- `-javaagent:/path/to/transmittable-thread-local-2.x.x.jar`
oldratlee's avatar
oldratlee 已提交
171 172 173

**NOTE**

174 175
* Agent modify the jdk classes, add code refer to the class of `TTL`, so the jar of `TTL Agent` should add to `bootclasspath`.
* `TTL Agent` modify the class by `javassist`, so the Jar of `javassist` should add to `bootclasspath` too.
oldratlee's avatar
oldratlee 已提交
176 177 178 179

Java command example:

```bash
180 181
java -Xbootclasspath/a:transmittable-thread-local-2.0.0.jar \
    -javaagent:transmittable-thread-local-2.0.0.jar \
oldratlee's avatar
oldratlee 已提交
182
    -cp classes \
183
    com.alibaba.ttl.threadpool.agent.demo.AgentDemo
oldratlee's avatar
oldratlee 已提交
184 185
```

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

oldratlee's avatar
oldratlee 已提交
189
:electric_plug: Java API Docs
190 191
======================

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

oldratlee's avatar
oldratlee 已提交
194
:cookie: Maven dependency
oldratlee's avatar
oldratlee 已提交
195 196 197 198 199
=====================================

```xml
<dependency>
	<groupId>com.alibaba</groupId>
200
	<artifactId>transmittable-thread-local</artifactId>
oldratlee's avatar
oldratlee 已提交
201
	<version>2.1.0</version>
oldratlee's avatar
oldratlee 已提交
202 203 204
</dependency>
```

205
Check available version at [search.maven.org](http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22com.alibaba%22%20AND%20a%3A%22transmittable-thread-local%22).
oldratlee's avatar
oldratlee 已提交
206

oldratlee's avatar
oldratlee 已提交
207
:books: Related resources
oldratlee's avatar
oldratlee 已提交
208 209
=====================================

oldratlee's avatar
oldratlee 已提交
210 211 212 213 214 215 216 217 218
Jdk core classes
----------------------------

* [WeakHashMap](http://docs.oracle.com/javase/7/docs/api/java/util/WeakHashMap.html)
* [InheritableThreadLocal](http://docs.oracle.com/javase/7/docs/api/java/lang/InheritableThreadLocal.html)

Java Agent
----------------------------

oldratlee's avatar
oldratlee 已提交
219
* [Java Agent规范](http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html)
oldratlee's avatar
oldratlee 已提交
220 221 222
* [Java SE 6 新特性: Instrumentation 新功能](http://www.ibm.com/developerworks/cn/java/j-lo-jse61/)
* [Creation, dynamic loading and instrumentation with javaagents](http://dhruba.name/2010/02/07/creation-dynamic-loading-and-instrumentation-with-javaagents/)
* [JavaAgent加载机制分析](http://alipaymiddleware.com/jvm/javaagent%E5%8A%A0%E8%BD%BD%E6%9C%BA%E5%88%B6%E5%88%86%E6%9E%90/)
oldratlee's avatar
oldratlee 已提交
223 224 225 226

Javassist
----------------------------

oldratlee's avatar
oldratlee 已提交
227
* [Getting Started with Javassist](http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/tutorial/tutorial.html)