首页
首页
沸点
课程
直播
活动
竞赛
商城
APP
插件
搜索历史
清空
创作者中心
写文章
发沸点
写笔记
写代码
草稿箱
创作灵感
查看更多
会员
登录
注册
淘课之家
掘友等级
自由创业者
|
淘课之家
人,量力而行!事,看透再说!
获得徽章 0
动态
文章
专栏
沸点
收藏集
关注
作品
赞
0
文章 0
沸点 0
赞
0
返回
|
搜索文章
淘课之家
自由创业者 @淘课之家
·
3年前
关注
大厂面试Linux就这几个问题
1.CPU负载和CPU利用率的区别是什么?首先,我们可以通过uptime,w或者top命令看到CPU的平均负载。LoadAverage:负载的3个数字,比如上图的4.86,...
赞
1
分享
淘课之家
自由创业者 @淘课之家
·
3年前
举报
Java基础面试(4):对象头具体都包含哪些内容?
在我们常用的Hotspot虚拟机中,对象在内存中布局实际包含3个部分:
1、对象头
2、实例数据
3、对齐填充
而对象头包含两部分内容,Mark Word中的内容会随着锁标志位而发生变化,所以只说存储结构就好了。
对象自身运行时所需的数据,也被称为Mark Word,也就是用于轻量级锁和偏向锁的关键点。具体的内容包含对象的hashcode、分代年龄、轻量级锁指针、重量级锁指针、GC标记、偏向锁线程ID、偏向锁时间戳。
存储类型指针,也就是指向类的元数据的指针,通过这个指针才能确定对象是属于哪个类的实例。
如果是数组的话,则还包含了数组的长度
展开
收起
查看大图
向左旋转
向右旋转
分享
评论
点赞
淘课之家
自由创业者 @淘课之家
·
3年前
关注
HashMap默认容量的选择
集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生。在日常开发中,我们经常会像如下方式以下创建一个...
赞
1
分享
淘课之家
自由创业者 @淘课之家
·
3年前
关注
HashMap灵魂拷问从入门到入土,面试官最后找不到北了!
前言作为一个在互联网公司面一次拿一次Offer的面霸,打败了无数竞争对手,每次都只能看到无数落寞的身影失望的离开,略感愧疚(请允许我使用一下夸张的修辞手法)。于是在一个寂寞...
赞
评论
分享
淘课之家
自由创业者 @淘课之家
·
3年前
举报
Java基础面试(3):synchronized锁的优化机制了解多少?
从JDK1.6版本之后,synchronized本身也在不断优化锁的机制,有些情况下他并不会是一个很重量级的锁了。优化机制包括自适应锁、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁。
锁的状态从低到高依次为无锁->偏向锁->轻量级锁->重量级锁,升级的过程就是从低到高,降级在一定条件也是有可能发生的。
自旋锁:由于大部分时候,锁被占用的时间很短,共享变量的锁定时间也很短,所有没有必要挂起线程,用户态和内核态的来回上下文切换严重影响性能。自旋的概念就是让线程执行一个忙循环,可以理解为就是啥也不干,防止从用户态转入内核态,自旋锁可以通过设置-XX:+UseSpining来开启,自旋的默认次数是10次,可以使用-XX:PreBlockSpin设置。
自适应锁:自适应锁就是自适应的自旋锁,自旋的时间不是固定时间,而是由前一次在同一个锁上的自旋时间和锁的持有者状态来决定。
锁消除:锁消除指的是JVM检测到一些同步的代码块,完全不存在数据竞争的场景,也就是不需要加锁,就会进行锁消除。
锁粗化:锁粗化指的是有很多操作都是对同一个对象进行加锁,就会把锁的同步范围扩展到整个操作序列之外。
偏向锁:当线程访问同步块获取锁时,会在对象头和栈帧中的锁记录里存储偏向锁的线程ID,之后这个线程再次进入同步块时都不需要CAS来加锁和解锁了,偏向锁会永远偏向第一个获得锁的线程,如果后续没有其他线程获得过这个锁,持有锁的线程就永远不需要进行同步,反之,当有其他线程竞争偏向锁时,持有偏向锁的线程就会释放偏向锁。可以用过设置-XX:+UseBiasedLocking开启偏向锁。
轻量级锁:JVM的对象的对象头中包含有一些锁的标志位,代码进入同步块的时候,JVM将会使用CAS方式来尝试获取锁,如果更新成功则会把对象头中的状态位标记为轻量级锁,如果更新失败,当前线程就尝试自旋来获得锁。
整个锁升级的过程非常复杂,我尽力去除一些无用的环节,简单来描述整个升级的机制。
简单点说,偏向锁就是通过对象头的偏向线程ID来对比,甚至都不需要CAS了,而轻量级锁主要就是通过CAS修改对象头锁记录和自旋来实现,重量级锁则是除了拥有锁的线程其他全部阻塞。
展开
收起
查看大图
向左旋转
向右旋转
分享
评论
点赞
淘课之家
自由创业者 @淘课之家
·
3年前
关注
HashMap为什么线程不安全?
目录1.jdk1.7中的HashMap1.1扩容造成死循环分析过程1.2扩容造成数据丢失分析过程2.jdk1.8中HashMap总结前言:我们都知道HashMap是线程不安...
3
评论
分享
淘课之家
自由创业者 @淘课之家
·
3年前
举报
Java基础面试(2):说说进程和线程的区别?
进程是程序的一次执行,是系统进行资源分配和调度的独立单位,他的作用是是程序能够并发执行提高资源利用率和吞吐率。
由于进程是资源分配和调度的基本单位,因为进程的创建、销毁、切换产生大量的时间和空间的开销,进程的数量不能太多,而线程是比进程更小的能独立运行的基本单位,他是进程的一个实体,可以减少程序并发执行时的时间和空间开销,使得操作系统具有更好的并发性。
线程基本不拥有系统资源,只有一些运行时必不可少的资源,比如程序计数器、寄存器和栈,进程则占有堆、栈。
展开
分享
评论
点赞
淘课之家
自由创业者 @淘课之家
·
3年前
举报
Java基础面试(1):知道synchronized原理吗?
synchronized是java提供的原子性内置锁,这种内置的并且使用者看不到的锁也被称为监视器锁,使用synchronized之后,会在编译之后在同步的代码块前后加上monitorenter和monitorexit字节码指令,他依赖操作系统底层互斥锁实现。他的作用主要就是实现原子性操作和解决共享变量的内存可见性问题。
执行monitorenter指令时会尝试获取对象锁,如果对象没有被锁定或者已经获得了锁,锁的计数器+1。此时其他竞争锁的线程则会进入等待队列中。
执行monitorexit指令时则会把计数器-1,当计数器值为0时,则锁释放,处于等待队列中的线程再继续竞争锁。
synchronized是排它锁,当一个线程获得锁之后,其他线程必须等待该线程释放锁后才能获得锁,而且由于Java中的线程和操作系统原生线程是一一对应的,线程被阻塞或者唤醒时时会从用户态切换到内核态,这种转换非常消耗性能。
从内存语义来说,加锁的过程会清除工作内存中的共享变量,再从主内存读取,而释放锁的过程则是将工作内存中的共享变量写回主内存。
实际上大部分时候我认为说到monitorenter就行了,但是为了更清楚的描述,还是再具体一点。
如果再深入到源码来说,synchronized实际上有两个队列waitSet和entryList。
1、当多个线程进入同步代码块时,首先进入entryList
2、有一个线程获取到monitor锁后,就赋值给当前线程,并且计数器+1
3、如果线程调用wait方法,将释放锁,当前线程置为null,计数器-1,同时进入waitSet等待被唤醒,调用notify或者notifyAll之后又会进入entryList竞争锁
4、如果线程执行完毕,同样释放锁,计数器-1,当前线程置为null
展开
收起
查看大图
向左旋转
向右旋转
赞过
分享
评论
1
淘课之家
关注了标签
神经网络
自由创业者 @淘课之家
淘课之家
关注了标签
Spring Boot
自由创业者 @淘课之家
淘课之家
关注了标签
负载均衡
自由创业者 @淘课之家
淘课之家
关注了标签
微服务
自由创业者 @淘课之家
淘课之家
关注了标签
数据挖掘
自由创业者 @淘课之家
淘课之家
关注了标签
Go
自由创业者 @淘课之家
淘课之家
关注了标签
创业
自由创业者 @淘课之家
淘课之家
关注了标签
Redis
自由创业者 @淘课之家
淘课之家
关注了标签
MySQL
自由创业者 @淘课之家
淘课之家
关注了标签
程序员
自由创业者 @淘课之家
淘课之家
关注了标签
数据库
自由创业者 @淘课之家
淘课之家
关注了标签
Java
自由创业者 @淘课之家
下一页
个人成就
文章被点赞
3
文章被阅读
1,508
掘力值
79
关注了
0
关注者
1
收藏集
0
关注标签
12
加入于
2021-01-31