1. 程式人生 > 實用技巧 >使用ThreadLocal建立執行緒上下文

使用ThreadLocal建立執行緒上下文

1 定義上下文介面

public interface ThreadContext {

    /**
     * 新增屬性
     * 
     * @param key
     * @param object
     */
    void add(String key, Object object);

    /**
     * 獲得屬性
     * 
     * @param key
     * @return
     */
    Object get(String key);

}

2 定義上下文實現類

public class TaskThreadContext implements ThreadContext {

    /** 訂單id */
    private int orderId;

    /** 任務開始執行時間 */
    private long startTime;

    /** task context map */
    public static Map<String, Object> taskContextMap = new HashMap<>();

    /**
     * 新增
     *
     * @param key
     * @param object
     */
    @Override
    public void add(String key, Object object) {
        if (null == taskContextMap) {
            taskContextMap = new HashMap<String, Object>();
        }
        taskContextMap.put(key, object);
    }

    @Override
    public Object get(String key) {
        if (null == taskContextMap) {
            taskContextMap = new HashMap<String, Object>();
        }
        return taskContextMap.get(key);
    }

    public int getOrderId() {
        return orderId;
    }

    public void setOrderId(int orderId) {
        this.orderId = orderId;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }
}

3 定義ThreadContext持有類

public class TaskContextHolder {

    /** task context threadLocal */
    private static final ThreadLocal<ThreadContext> TASK_CONTEXT = new ThreadLocal<>();

    public static ThreadContext getTaskContext() {
        if (TASK_CONTEXT.get() == null) {
            TASK_CONTEXT.set(new TaskThreadContext());
        }
        return TASK_CONTEXT.get();
    }

    public static void setTaskContext(ThreadContext taskContext) {
        TASK_CONTEXT.set(taskContext);
    }

    public static void add(String key, Object param) {
        getTaskContext().add(key, param);
    }

    public static Object get(String key) {
        return getTaskContext().get(key);
    }
}

4 測試

public class Test {
    public static void main(String[] args) {
        // 建立執行緒t1
        Thread thread = new Thread(() -> {
            // 新增上下文
            TaskThreadContext context = new TaskThreadContext();
            context.setOrderId(1);
            TaskContextHolder.setTaskContext(context);
            // 新增普通屬性
            TaskContextHolder.add("t1", "Hello t1");

            TaskThreadContext taskContext = (TaskThreadContext) TaskContextHolder.getTaskContext();
            System.out.println("t1 order id:" + taskContext.getOrderId());
            System.out.println("t1:" + TaskContextHolder.get("t1"));
        }, "t1");
        thread.start();

        // 建立執行緒t2
        Thread thread2 = new Thread(() -> {
            // 新增上下文
            TaskThreadContext context = new TaskThreadContext();
            context.setOrderId(2);
            TaskContextHolder.setTaskContext(context);
            // 新增普通屬性
            TaskContextHolder.add("t2", "Hello t2");

            TaskThreadContext taskContext = (TaskThreadContext) TaskContextHolder.getTaskContext();
            System.out.println("t2 order id:" + taskContext.getOrderId());
            System.out.println("t2:" + TaskContextHolder.get("t2"));
        }, "t2");
        thread2.start();
    }
}

結果:

t1 order id:1
t1:Hello t1
t2 order id:2
t2:Hello t2