<commit_before>multi-thread context(MTC)
=====================================

<div align="right">
<a href="https://github.com/alibaba/multi-thread-context/blob/master/README-EN.md">English Documentation</a>
</div>

功能
----------------------------

在使用线程池等会Cache线程的组件情况下，完成多线程的Context传递。

`JDK`的[`java.lang.InheritableThreadLocal`](http://docs.oracle.com/javase/6/docs/api/java/lang/InheritableThreadLocal.html)类可以完成父子线程的Context传递。

但对于使用线程池等会Cache线程的组件的情况，线程由线程池创建好，并且线程是Cache起来反复使用的。这时父子线程关系的上下文传递已经没有意义，应用中要做上下文传递，实际上是在把 **任务提交给线程池时**的上下文传递到 **任务执行时**。

如有问题欢迎 [提交Issue](https://github.com/alibaba/multi-thread-context/issues) 或 [Mail](mailto:<EMAIL>)。

需求场景
----------------------------

下面列出需求场景，即是整理出`MTC`的实际需求。

### 应用容器或上层框架跨应用代码给下层SDK传递信息

举个场景，淘宝的App Engine（如JAE或是TAE，PAAS平台）跑了ISV（这里指卖家的应用提供商）的应用，多个淘宝卖家会在淘宝平台上购买并使用这个应用。

数据安全需要防止ISV的应用拿到多个卖家家数据。

解决的问题其中一环是：处理过程关联了一个卖家的上下文，在这个上下文中应用只能处理（读&写）这个卖家的数据。

请求由卖家发起（如从Web请求时进入App Engine），App Engine可以知道是从哪个卖家，在Web请求时在上下文中设置好卖家ID。

应用处理数据（DB、Cache、消息 etc.）是通过App Engine提供的服务SDK来完成。当应用处理数据时，SDK检查数据所属的卖家是否和上下文中的卖家ID一致，不一致则拒绝数据的读写。

应用代码会使用线程池，并且这样的使用是正常的业务需求。卖家ID的从要App Engine传递到下层SDK，要支持这样的用法。

\# 当然，仅仅通过这样一个手段是不能解决数据安全的，每次处理数据时，应用可能把数据汇聚到内存中，再批量导出或是自动Post出去。这个要通过其它的手段来解决，如代码白盒检查，内存分析，禁止应用自动对外请求。

### 日志记录系统上下文

App Engine的日志（如，SDK会记录日志）要记录系统上下文。由于不限制用户应用使用线程池，系统的上下文需要能跨线程的传递，且不影响应用代码。

使用说明
=====================================

1. 简单使用
----------------------------

父线程给子线程传递Context。

示例代码：

```java
// 在父线程中设置
MtContextThreadLocal<String> parent = new MtContextThreadLocal<String>();
parent.set("value-set-in-parent");

// =====================================================
<commit_msg>improve readme<commit_after>multi-thread context(MTC)
=====================================

<div align="right">
<a href="https://github.com/alibaba/multi-thread-context/blob/master/README-EN.md">English Documentation</a>
</div>

功能
----------------------------

在使用线程池等会Cache线程的组件情况下，完成多线程的Context传递。

`JDK`的[`java.lang.InheritableThreadLocal`](http://docs.oracle.com/javase/6/docs/api/java/lang/InheritableThreadLocal.html)类可以完成父子线程的Context传递。

但对于使用线程池等会Cache线程的组件的情况，线程由线程池创建好，并且线程是Cache起来反复使用的。这时父子线程关系的上下文传递已经没有意义，应用中要做上下文传递，实际上是在把 **任务提交给线程池时**的上下文传递到 **任务执行时**。

如有问题欢迎 [提交Issue](https://github.com/alibaba/multi-thread-context/issues) 或 [Mail](mailto:<EMAIL>)。

需求场景
----------------------------

下面列出需求场景，即是整理出`MTC`的实际需求。

### 应用容器或上层框架跨应用代码给下层SDK传递信息

举个场景，淘宝的App Engine（如JAE或是TAE，PAAS平台）跑了ISV（这里指卖家的应用提供商）的应用，多个淘宝卖家会在淘宝平台上购买并使用这个应用。

数据安全需要防止ISV的应用拿到多个卖家家数据。

解决的问题其中一环是：处理过程关联了一个卖家的上下文，在这个上下文中应用只能处理（读&写）这个卖家的数据。

请求由卖家发起（如从Web请求时进入App Engine），App Engine可以知道是从哪个卖家，在Web请求时在上下文中设置好卖家ID。

应用处理数据（DB、Cache、消息 etc.）是通过App Engine提供的服务SDK来完成。当应用处理数据时，SDK检查数据所属的卖家是否和上下文中的卖家ID一致，不一致则拒绝数据的读写。

应用代码会使用线程池，并且这样的使用是正常的业务需求。卖家ID的从要App Engine传递到下层SDK，要支持这样的用法。

\# 当然，仅仅通过这样一个手段是不能解决数据安全的，每次处理数据时，应用可能把数据汇聚到内存中，再批量导出或是自动Post出去。这个要通过其它的手段来解决，如代码白盒检查，内存分析，禁止应用自动对外请求。

### 日志记录系统上下文

App Engine的日志（如，SDK会记录日志）要记录系统上下文。由于不限制用户应用使用线程池，系统的上下文需要能跨线程的传递，且不影响应用代码。

使用说明
=====================================

使用类[`MtContextThreadLocal`](https://github.com/alibaba/multi-thread-context/blob/master/src/main/java/com/alibaba/mtc/MtContextThreadLocal.java)来保存上下言，并跨线程池传递。

[`MtContextThreadLocal`](https://github.com/alibaba/multi-thread-context/blob/master/src/main/java/com/alibaba/mtc/MtContextThreadLocal.java)继承[`java.lang.InheritableThreadLocal`](http://docs.oracle.com/javase/6/docs/api/java/lang/InheritableThreadLocal.html)，并且使用方式也类似。具体使用方式见下面的说明。

1. 简单使用
----------------------------

父线程给子线程传递Context。

示例代码：

```java
// 在父线程中设置
MtContextThreadLocal<String> parent = new MtContextThreadLocal<String>();
parent.set("value-set-in-parent");

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

{'fraction_non_alphanumeric': 0.2303385763796321, 'fraction_numerical': 0.0013329778725673154, 'mean_word_length': 6.688524590163935, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4239485', 'n_tokens_mistral': 2206, 'n_tokens_neox': 2453, 'n_words': 101}