Java基础小知识点积累

2024-03-18  本文已影响0人  Cherron

对象一定分配在堆中吗?有没有了解逃逸分析技术?

volatile:可见性、顺序性

保证并发编程的三要素(可见性、顺序性、原子性)之二,可结合AtomicInteger等对象使用
volatile 本质是在告诉 jvm 当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读 取
使用 volatile 一般用于 状态标记量 和 单例模式的双检锁。
1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对 其他线程来说是立即可见的,volatile 关键字会强制将修改的值立即写入主存。
2)禁止进行指令重排序。

x = 2;//语句 1
y = 0;//语句 2
flag = true;//语句 3
x = 4;//语句 4
y = -1;//语句 5

由于flag 变量为 volatile 变量,那么在进行指令重排序的过程的时候,不会将语句 3 放到语句 1、
语句 2 前面,也不会将语句 3 放到语句 4、语句 5 后面。但是要注意语句 1 和语句 2 的顺序、语
句 4 和语句 5 的顺序是不做任何保证的。

Thread中start()和run()区别

start()方法被用来启动新创建的线程,而且 start()内部调用了 run()方法,这和直接调用 run()方法的 效果不一样。当你调用 run()方法的时候,只会是在原来的线程中调用,没有新的线程启动,start() 方法才会启动新线程。

Java对象创建过程

  1. 类加载器将类加载到内存里
  2. 对类的静态变量、成员变量、静态代码块进行初始化
  3. 根据类信息得知目标对象大小,在堆内存里分配空间
  1. 目标对象里的普通成员变量初始化为零值,int为0,对象为null
  2. 设置对象头:如类元信息、GC分代年龄、hashcode、锁标记等
  3. 执行目标对象内部生成的 init 方法

为什么ConcurrentHashMap的key、value不允许为null,而HashMap允许?

  1. 防止歧义:get(key)的时候返回null,不确定是key不存在,还是value=null
  2. HashMap可以使用containsKey(key)来判断key是否存在,ConcurrentHashMap使用containsKey()后再使用get(key)不具有原子性,无法做出判断

ThreadLocal会出现内存泄漏吗?

static class ThreadLocalMap {

        /**
         * The entries in this hash map extend WeakReference, using
         * its main ref field as the key (which is always a
         * ThreadLocal object).  Note that null keys (i.e. entry.get()
         * == null) mean that the key is no longer referenced, so the
         * entry can be expunged from table.  Such entries are referred to
         * as "stale entries" in the code that follows.
         */
        static class Entry extends WeakReference<ThreadLocal<?>> {

若ThreadLocal对象无其它强引用,那么可能会被GC,导致ThreadLocalMap的key为null,其对应的value就无法被访问,出现内存泄露

创建线程池的办法

  1. 使用Executors
  1. 使用 ThreadPoolExecutor 类的构造方法创建自定义线程池
上一篇 下一篇

猜你喜欢

热点阅读