美文网首页
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