美文网首页
ThreadLocal 备忘

ThreadLocal 备忘

作者: DH大黄 | 来源:发表于2021-06-23 20:57 被阅读0次

    计算数组下标 int i = key.threadLocalHashCode & (table.length - 1);

    关于Hash冲突

    • key值相同,直接覆盖
    • key值不同,但是hash值相同。开放寻址法
    private void set(ThreadLocal<?> key, Object value) {
    
        // We don't use a fast path as with get() because it is at
        // least as common to use set() to create new entries as
        // it is to replace existing ones, in which case, a fast
        // path would fail more often than not.
    
        Entry[] tab = table;
        int len = tab.length;
        int i = key.threadLocalHashCode & (len-1);
    
        for (Entry e = tab[i];
             e != null;
             e = tab[i = nextIndex(i, len)]) {
            ThreadLocal<?> k = e.get();
    
            if (k == key) {
                e.value = value;
                return;
            }
    
            if (k == null) {
                replaceStaleEntry(key, value, i);
                return;
            }
        }
    
        tab[i] = new Entry(key, value);
        int sz = ++size;
        if (!cleanSomeSlots(i, sz) && sz >= threshold)
            rehash();
    }
    

    正常来说,ThreadLocal是线程独占的,不会影响到其他线程。但是我们可以使用InheritableThreadLocal ,在创建线程的时候,把当前线程的InheritableThreadLocal 赋值给被创建的线程

    private void init(ThreadGroup g, Runnable target, String name,
                          long stackSize, AccessControlContext acc,
                          boolean inheritThreadLocals) {
      if (name == null) {
          throw new NullPointerException("name cannot be null");
      }
    
      this.name = name;
    
      Thread parent = currentThread();
      SecurityManager security = System.getSecurityManager();
      if (g == null) {
          /* Determine if it's an applet or not */
    
          /* If there is a security manager, ask the security manager
             what to do. */
          if (security != null) {
              g = security.getThreadGroup();
          }
    
          /* If the security doesn't have a strong opinion of the matter
             use the parent thread group. */
          if (g == null) {
              g = parent.getThreadGroup();
          }
      }
    
      /* checkAccess regardless of whether or not threadgroup is
         explicitly passed in. */
      g.checkAccess();
    
      /*
       * Do we have the required permissions?
       */
      if (security != null) {
          if (isCCLOverridden(getClass())) {
              security.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION);
          }
      }
    
      g.addUnstarted();
    
      this.group = g;
      this.daemon = parent.isDaemon();
      this.priority = parent.getPriority();
      if (security == null || isCCLOverridden(parent.getClass()))
          this.contextClassLoader = parent.getContextClassLoader();
      else
          this.contextClassLoader = parent.contextClassLoader;
      this.inheritedAccessControlContext =
              acc != null ? acc : AccessController.getContext();
      this.target = target;
      setPriority(priority);
        // 赋值 inheritableThreadLocal
      if (inheritThreadLocals && parent.inheritableThreadLocals != null)
          this.inheritableThreadLocals =
              ThreadLocal.createInheritedMap(parent.inheritableThreadLocals);
      /* Stash the specified stack size in case the VM cares */
      this.stackSize = stackSize;
    
      /* Set thread ID */
      tid = nextThreadID();
    }
    

    相关文章

      网友评论

          本文标题:ThreadLocal 备忘

          本文链接:https://www.haomeiwen.com/subject/fyhiyltx.html