总体理解

  • 听起来如果是权限控制时使用ThreadLocal,并不是出于减少查询Redis数据库的目的,而是为了保证数据完整性,Thread线程独占某个资源避免高并发时出现数据异常和串号的情况。
  • 譬如对数据库的getConnection,如果使用共享变量,在高并发时很可能会出现死锁,因此需要用到ThreadLocal,这样每个线程的变量是自己独立的副本,用完都销毁,相互不影响。
  • 总的来说,ThreadLocal 适用于每个线程需要自己独立的实例且该实例需要在多个方法中被使用,也即变量在线程间隔离而在方法或类间共享的场景。后文会通过实例详细阐述该观点。另外,该场景下,并非必须使用 ThreadLocal ,其它方式完全可以实现同样的效果,只是 ThreadLocal 使得实现更简洁。

ThreadLocal

  • 测试使用….
    1. @Test
    2. public void test(){
    3. ThreadLocal<String> mStringThreadLocal = new ThreadLocal<>();
    4. mStringThreadLocal.set("1aaaaa");
    5. String bbbb = mStringThreadLocal.get();
    6. System.out.println(bbbb);
    7. }

实验记录

  • 不同线程之间的数据是不共享的.
    1. private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>() {
    2. public Integer initialValue() {
    3. return 0;
    4. }
    5. };
    6. public int getNextNum() {
    7. threadLocal.set(threadLocal.get() + 1);
    8. return threadLocal.get();
    9. }
    10. public static void main(String[] args) {
    11. ThreadLocalTest threadLocalTest = new ThreadLocalTest();
    12. ThreadTest t1 = new ThreadTest(threadLocalTest);
    13. ThreadTest t2 = new ThreadTest(threadLocalTest);
    14. ThreadTest t3 = new ThreadTest(threadLocalTest);
    15. t1.start();
    16. t2.start();
    17. t3.start();
    18. t1.print();
    19. t2.print();
    20. t3.print();
    21. }
    22. private static class ThreadTest extends Thread {
    23. private ThreadLocalTest threadLocalTest;
    24. public ThreadTest(ThreadLocalTest threadLocalTest) {
    25. this.threadLocalTest = threadLocalTest;
    26. }
    27. public void run() {
    28. for (int i = 0; i < 3; i++) {
    29. System.out.println(Thread.currentThread().getName() + " = "
    30. + threadLocalTest.getNextNum());
    31. }
    32. }
    33. public void print() {
    34. for (int i = 0; i < 3; i++) {
    35. System.out.println(Thread.currentThread().getName() + " = "
    36. + threadLocalTest.getNextNum());
    37. }
    38. }
    39. }