前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java面试特殊知识点总结 part1

Java面试特殊知识点总结 part1

作者头像
Steve Wang
发布2021-02-04 10:33:11
3240
发布2021-02-04 10:33:11
举报
文章被收录于专栏:从流域到海域从流域到海域

并发与多线程

main方法里没有创建新的线程,执行main方法一共需要几个线程?

可以使用ManagementFactorygetThreadMXBean方法获取ThreadMXBean信息,进而获取线程信息进行查看。代码:

代码语言:javascript
复制
package Exercise;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class Test {
    public static void main(String[] args) {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);

        for (ThreadInfo threadInfo : threadInfos) {
            System.out.println(threadInfo.getThreadId() + ":" + threadInfo.getThreadName());
        }
    }
}

运行结果:

代码语言:javascript
复制
6:Monitor Ctrl-Break
5:Attach Listener
4:Signal Dispatcher
3:Finalizer
2:Reference Handler
1:main

答案是6个,通过每个线程的名字可以知道他们的作用。

ThreadLocal

ThreadLocal为每个线程创建一个变量的副本,对彼此不可见,它基于ThreadLocalMap实现。

核心机制如下:

  1. 每个Thread线程内部都有一个map(ThreadLocalMap)。
  2. map里面存储线程本地对象key和线程变量副本value
  3. Thread内部的map是由ThreadLocal维护的,由ThreadLocal负责向map获取和设置线程的变量值。

每个线程只能获取自己的副本值,不能获取其他线程的,这样就形成了隔离,互不干扰。

ThreadLocal类提供了以下几个核心方法:

1.get()方法:获取当前线程的副本变量值。 2.set()方法:设置当前线程的副本变量值。 3.remove()方法:移除当前线程的副本变量值。 4.initilaValue()方法:初始化当前线程的副本变量值,初始化为null

ThreadLocalMapThreadLocal内部的一个map实现, 它和HashMap实现自Map接口不一样,它没有实现任何接口,仅供ThreadLocal内部使用,数据结构采用数组加开放地址法,Entry继承自WeakReference,是基于ThreadLocal场景下实现的特殊Map,源码见参考文献第一篇。

ThreadLocal的应用场景:
  1. 在对象进行跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束。
  2. 线程间数据隔离。
  3. 进行事务操作,用于存储事务信息。
  4. ·数据库连接,Session会话管理。

发生了死锁,如何排查

使用jps获取发生死锁的进程号。 使用jstack+进程号查看该进程堆栈,它会详细显示死锁数量,相关联的线程,发生死锁的大致代码位置等信息。

jconsole也可以查看相关信息。

黑名单功能如何实现

使用写时复制容器CopyOnWriteArrayList实现。

什么是写时复制容器

写时复制是指,在并发访问的场景下,需要修改Java中容器中的元素时,不直接修改该容器中,而是先复制一份副本,在副本上进行修改。修改完成之后,将指向原来容器的引用指向新的副本容器。

写时复制带来的影响
  1. 由于不会修改原始容器,只修改副本容器,可以对原始容器进行并发地读。其次,实现了读操作和写操作的分离:读操作发生在原始容器上,写操作发生在副本容器上。
  2. 数据一致性问题:读操作的线程可能不会立即读取到新修改的数据,因为修改操作可能会发生在副本上,但最终修改操作会完成并更新容器,因此只能保证最终一致性。
写时复制容器

JDK中提供了CopyOnWriteArrayListCopyOnWriteArraySet类,但是没有提供CopyOnWriteHashMap,可以自己实现一个。

写时复制容器适用的场景

CopyOnWrite容器适用于读多写少的场景。因为写操作时,需要复制一个容器,造成内存开销很大,也需要根据实际应用把握初始容器的大小。

不适合数据的强一致性场合。若要求数据修改之后能立即被读到,则不能使用写时复制技术,因为它只能保证最终一致性。

参考文献

深入源码理解ThreadLocal和ThreadLocalMap

面试官:知道ThreadLocal嘛?谈谈你对它的理解?(基于jdk1.8)

JAVA中写时复制(Copy-On-Write)Map实现

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-01-30 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 并发与多线程
    • main方法里没有创建新的线程,执行main方法一共需要几个线程?
      • ThreadLocal
        • 发生了死锁,如何排查
          • 黑名单功能如何实现
            • 写时复制容器适用的场景
              • 参考文献
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档