Java并发编程(一)常见知识点

思维导图


在这里插入图片描述




一、常见知识点

1.线程与进程的区别:

在这里插入图片描述


2.多线程中的上下文切换:在这里插入图片描述


4.原子操作,JUC中原子操作类有哪些:

在这里插入图片描述


5.CAS操作及缺点:

在这里插入图片描述

关于ABA问题,详见以下链接:
CAS中的ABA问题


6.java中的volatile变量作用:

在这里插入图片描述


7.volatile和atomic变量区别:

在这里插入图片描述


8.lock接口与synchronized区别:

在这里插入图片描述


9.乐观锁和悲观锁的理解及实现:

在这里插入图片描述


10.死锁:

在这里插入图片描述


11.callable及future:

在这里插入图片描述


12.futureTask的底层原理:

在这里插入图片描述


13.阻塞队列及实现原理:

在这里插入图片描述

这两个附加的操作是:

  • 在队列为空时,获取元素的线程会等待队列变为非空。
  • 当队列满时,存储元素的线程会等待队列可用。

常用于生产消费者模型


14.不可变对象对并发应用的帮助

在这里插入图片描述


15.生产消费者模型作用:

在这里插入图片描述


16.copyOnWriteArrayList应用场景:

在这里插入图片描述


17.java单例:

在这里插入图片描述


18.双重检查锁定DCL的单例:

在这里插入图片描述


19.AQS:

在这里插入图片描述


20.wait、notify、notifyAll为什么不在thread类中:

在这里插入图片描述

类似问题:为什么 sleep() 方法不定义在object中?

  • sleep()是Thread静态类,属于线程级别的。
  • 是一个线程的运行状态控制,为了让线程在限定的时间后去执行。

详细如下链接:
关于为什么线程通信的方法wait()、notify()、notifyAll()被定义在Object类里面?而sleep为什么定义在Thread类里面?

为什么wait方法在object类中,sleep方法在Thread类中?


21 ThreadLocal

21.1 作用

(1)通常情况下,我们创建的变量是可以被任何⼀个线程访问并修改的。
如果想实现每一个线程都有自己的专属本地变量该如何解决呢?

(2)ThreadLocal 类主要解决的就是让每个线程绑定自己的值。可以将 ThreadLocal 类形象的⽐喻成存放数据的盒⼦,盒⼦中可以存储每个线程的私有数据

(3)如果你创建了⼀个 ThreadLocal 变量,那么访问这个变量的每个线程都会有这个变量的本地副本。
他们可以使⽤ get() 和 set() ⽅法来获取默认值或将其值更改为当前线程所存的副本的值,从⽽避免了线程安全问题。

21.2 应用场景

(1)进行对象跨层传递时,可以使用ThreadLocal可以避免多次传递,打破层次间的约束

(2)线程间数据隔离

(3)进行事务操作,用于存储线程事务信息

(4)数据库连接、session会话管理

21.3 原理

21.3.1 数据结构如下图:

在这里插入图片描述

21.3.2 ThreadLocal类的set()方法
public void set(T value) {
    //获取当前请求的线程
    Thread t = Thread.currentThread();
    //取出 Thread 类内部的 threadLocals 变量(哈希表结构)
    ThreadLocalMap map = getMap(t);
    if (map != null)
        // 将需要存储的值放入到这个哈希表中
        map.set(this, value);
    else
        createMap(t, value);
}
ThreadLocalMap getMap(Thread t) {
    return t.threadLocals;
}

(1)最终的变量是放在了当前线程的 ThreadLocalMap 中,并不是存在 ThreadLocal 上,ThreadLocal 可以理解为只是ThreadLocalMap的封装,传递了变量值。

(2)ThrealLocal 类中可以通过Thread.currentThread()获取到当前线程对象后,直接通过getMap(Thread t)可以访问到该线程的ThreadLocalMap对象。

(3)每个Thread中都具备一个ThreadLocalMap,而ThreadLocalMap可以存储以ThreadLocal为 key ,Object 对象为 value 的键值对。

ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
    //......
}

(4)ThreadLocalMap是ThreadLocal的静态内部类。
在这里插入图片描述

21.4 ThreadLocal 内存泄露

21.4.1 强弱引用

(1)强引用:new对象,不会被垃圾回收器回收,即使抛出outofmemoryerror使程序停止

如何回收强引用:显式将引用赋值为null,jvm就会在合适的时候回收

(2)弱引用:jvm进行垃圾回收时候,无论内存是否充足,都会回收别弱引用关联的对象,一般在缓存中使用。

21.4.2 问题是怎么导致的?

(1)ThreadLocalMap 中使用的 key 为 ThreadLocal 的弱引用,而 value 是强引用。所以,如果 ThreadLocal 没有被外部强引用的情况下,在垃圾回收的时候,key 会被清理掉,而 value 不会被清理掉。

(2)ThreadLocalMap 中就会出现 key 为 null 的 Entry。假如我们不做任何措施的话,value 永远无法被 GC 回收,这个时候就可能会产生内存泄露。

(3)hreadLocalMap 实现中已经考虑了这种情况,在调用 set()、get()、remove() 方法的时候,会清理掉 key 为 null 的记录。

static class Entry extends WeakReference<ThreadLocal<?>> {
    /** The value associated with this ThreadLocal. */
    Object value;

    Entry(ThreadLocal<?> k, Object v) {
        super(k);
        value = v;
    }
}
21.4.3 如何解决?

(1)使用完 ThreadLocal方法后 最好手动调用remove()方法

(2)将ThreadLocal变量定义为private static


一篇跳转—Java并发编程(二)内存模型及线程池


本篇文章主要参考链接如下:

参考链接1-King说Java

参考链接2-JavaGuide


持续更新中…

随心所往,看见未来。Follow your heart,see light!

欢迎点赞、关注、留言,一起学习、交流!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值