最新要闻
- 加点广告怎么了 爱奇艺新专利可在弹幕中显示广告
- 环球动态:狂飙8000MHz!朗科Z RGB DDR5-8000 16GB电镀银内存图赏
- 每日短讯:1:1复刻仿生人手 现实版《西部世界》公司众筹开启
- 全球头条:5G是高铁 6G就是飞机!工信部:全面推进6G技术研发
- 焦点热文:公司丢货要求全体员工均摊1万赔款:新员工拒赔反被怀疑偷东西
- 当前报道:纬德信息(688171)3月1日主力资金净买入105.72万元
- 旅俄大熊猫画风突变体重狂飙40公斤:摸爬滚打样样精通
- 百事通!特斯拉Model 2被曝成本大降37% 比丰田卡罗拉还低
- 世界短讯!打赢了!科比坠机照片泄露案其遗孀获赔2885万美元
- 天天热头条丨惊险一幕:女子用火车站自动扶梯运行李 把下面男子砸骨折
- 【全球速看料】玩游戏需自备爆米花:《最终幻想16》主线过场动画超11小时
- 当前信息:索泰RTX 4090月白深度测试:真孤独求败!A卡没得玩了
- 网友晒视频广州一特斯拉在停车场连撞多车 司机下车就跑:又踩错了吗
- 当前看点!设计时速100公里!上海苏州互通地铁今起试跑:苏州坐地铁直达
- 医院拍CT有位患者叫熊猫 结果竟是真熊猫:网友祝福“国宝”尽快好起来
- 丰田拆完一辆特斯拉Model Y后被震撼了 高管惊叹:我们远远落后
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
全球百事通!为什么95%的Java程序员人,都是用不好Synchronized?
Synchronized锁优化
jdk1.6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向锁、轻量级锁等技术来减少锁操作的开销。锁主要存在四中状态,依次是:无锁-> 偏向锁-> 轻量级锁-> 重量级锁,他们会随着竞争的激烈而逐渐升级。注意锁可以升级不可降级,这种策略是为了提高获得锁和释放锁的效率。
(资料图片)
锁优化
偏向锁
偏向锁是Java 6之后加入的新锁,它是一种针对加锁操作的优化手段,经过研究发现,在大多数情况下,锁不仅不存在多线程竞争,而且总是由同一线程多次获得,因此为了减少同一线程获取锁(会涉及到一些CAS操作,耗时)的代价而引入偏向锁。
偏向锁的核心思想是,如果一个线程获得了锁,那么锁就进入偏向模式,此时Mark Word 的结构也变为偏向锁结构,当这个线程再次请求锁时,无需再做任何同步操作,即获取锁的过程,这样就省去了大量有关锁申请的操作,从而也就提供程序的性能。
所以,对于没有锁竞争的场合,偏向锁有很好的优化效果,毕竟极有可能连续多次是同一个线程申请相同的锁。但是对于锁竞争比较激烈的场合,偏向锁就失效了,
因为这样场合极有可能每次申请锁的线程都是不相同的,因此这种场合下不应该使用偏向锁,否则会得不偿失,需要注意的是,偏向锁失败后,并不会立即膨胀为重量级锁,而是先升级为轻量级锁。下面我们接着了解轻量级锁。
引入偏向锁主要目的是:为了在无多线程竞争的情况下尽量减少不必要的轻量级锁执行路径。上面提到了轻量级锁的加锁解锁操作是需要依赖多次CAS原子指令的。
那么偏向锁是如何来减少不必要的CAS操作呢?我们可以查看Mark work的结构就明白了。只需要检查是否为偏向锁、锁标识为以及ThreadID即可
获取锁
- 检测Mark Word是否为可偏向状态,即是否为偏向锁1,锁标识位为01;
- 若为可偏向状态,则测试线程ID是否为当前线程ID,如果是,则执行步骤(5),否则执行步骤(3);
- 如果线程ID不为当前线程ID,则通过CAS操作竞争锁,竞争成功,则将Mark Word的线程ID替换为当前线程ID,否则执行线程(4);
- 通过CAS竞争锁失败,证明当前存在多线程竞争情况,当到达全局安全点,获得偏向锁的线程被挂起,偏向锁升级为轻量级锁,然后被阻塞在安全点的线程继续往下执行同步代码块;
- 执行同步代码块
释放锁偏向锁的释放采用了一种只有竞争才会释放锁的机制,线程是不会主动去释放偏向锁,需要等待其他线程来竞争。偏向锁的撤销需要等待全局安全点(这个时间点是上没有正在执行的代码)。其步骤如下:
- 暂停拥有偏向锁的线程,判断锁对象石是否还处于被锁定状态;
- 撤销偏向苏,恢复到无锁状态(01)或者轻量级锁的状态;
轻量级锁
倘若偏向锁失败,虚拟机并不会立即升级为重量级锁,它还会尝试使用一种称为轻量级锁的优化手段(1.6之后加入的),此时Mark Word 的结构也变为轻量级锁的结构。
轻量级锁能够提升程序性能的依据是“对绝大部分的锁,在整个同步周期内都不存在竞争”,注意这是经验数据。需要了解的是,轻量级锁所适应的场景是线程交替执行同步块的场合,如果存在同一时间访问同一锁的场合,就会导致轻量级锁膨胀为重量级锁。
引入轻量级锁的主要目的是在多没有多线程竞争的前提下,减少传统的重量级锁使用操作系统互斥量产生的性能消耗。当关闭偏向锁功能或者多个线程竞争偏向锁导致偏向锁升级为轻量级锁,则会尝试获取轻量级锁。
获取锁
- 判断当前对象是否处于无锁状态(hashcode、0、01),若是,则JVM首先将在当前线程的栈帧中建立一个名为锁记录(Lock Record)的空间,用于存储锁对象目前的Mark Word的拷贝(官方把这份拷贝加了一个Displaced前缀,即Displaced Mark Word);否则执行步骤(3);
- JVM利用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指正,如果成功表示竞争到锁,则将锁标志位变成00(表示此对象处于轻量级锁状态),执行同步操作;如果失败则执行步骤(3);
- 判断当前对象的Mark Word是否指向当前线程的栈帧,如果是则表示当前线程已经持有当前对象的锁,则直接执行同步代码块;否则只能说明该锁对象已经被其他线程抢占了,这时轻量级锁需要膨胀为重量级锁,锁标志位变成10,后面等待的线程将会进入阻塞状态;
释放锁
轻量级锁的释放也是通过CAS操作来进行的,主要步骤如下:
- 取出在获取轻量级锁保存在Displaced Mark Word中的数据;
- 用CAS操作将取出的数据替换当前对象的Mark Word中,如果成功,则说明释放锁成功,否则执行(3);
- 如果CAS操作替换失败,说明有其他线程尝试获取该锁,则需要在释放锁的同时需要唤醒被挂起的线程。
对于轻量级锁,其性能提升的依据是“对于绝大部分的锁,在整个生命周期内都是不会存在竞争的”,如果打破这个依据则除了互斥的开销外,还有额外的CAS操作,因此在有多线程竞争的情况下,轻量级锁比重量级锁更慢;
自旋锁
轻量级锁失败后,虚拟机为了避免线程真实地在操作系统层面挂起,还会进行一项称为自旋锁的优化手段。
这是基于在大多数情况下,线程持有锁的时间都不会太长,如果直接挂起操作系统层面的线程可能会得不偿失,毕竟操作系统实现线程之间的切换时需要从用户态转换到核心态,这个状态之间的转换需要相对比较长的时间,时间成本相对较高,因此自旋锁会假设在不久将来,
当前的线程可以获得锁,因此虚拟机会让当前想要获取锁的线程做几个空循环(这也是称为自旋的原因),一般不会太久,可能是50个循环或100循环,在经过若干次循环后,如果得到锁,就顺利进入临界区。
如果还不能获得锁,那就会将线程在操作系统层面挂起,这就是自旋锁的优化方式,这种方式确实也是可以提升效率的。最后没办法也就只能升级为重量级锁了。
线程的阻塞和唤醒需要CPU从用户态转为核心态,频繁的阻塞和唤醒对CPU来说是一件负担很重的工作,势必会给系统的并发性能带来很大的压力。
同时我们发现在许多应用上面,对象锁的锁状态只会持续很短一段时间,为了这一段很短的时间频繁地阻塞和唤醒线程是非常不值得的。所以引入自旋锁。
何谓自旋锁?所谓自旋锁,就是让该线程等待一段时间,不会被立即挂起,看持有锁的线程是否会很快释放锁。怎么等待呢?执行一段无意义的循环即可(自旋),和CAS类似。
自旋等待不能替代阻塞,先不说对处理器数量的要求(多核,貌似现在没有单核的处理器了),虽然它可以避免线程切换带来的开销,但是它占用了处理器的时间。
如果持有锁的线程很快就释放了锁,那么自旋的效率就非常好,反之,自旋的线程就会白白消耗掉处理的资源,它不会做任何有意义的工作,典型的占着茅坑不拉屎,这样反而会带来性能上的浪费。
所以说,自旋等待的时间(自旋的次数)必须要有一个限度,如果自旋超过了定义的时间仍然没有获取到锁,则应该被挂起。
自旋锁在JDK 1.4.2中引入,默认关闭,但是可以使用-XX:+UseSpinning开开启,在JDK1.6中默认开启。同时自旋的默认次数为10次,可以通过参数-XX:PreBlockSpin来调整;
如果通过参数-XX:preBlockSpin来调整自旋锁的自旋次数,会带来诸多不便。假如我将参数调整为10,但是系统很多线程都是等你刚刚退出的时候就释放了锁(假如你多自旋一两次就可以获取锁),你是不是很尴尬。
于是JDK1.6引入自适应的自旋锁,让虚拟机会变得越来越聪明。
适应自旋锁
JDK 1.6引入了更加聪明的自旋锁,即自适应自旋锁。所谓自适应就意味着自旋的次数不再是固定的,它是由前一次在同一个锁上的自旋时间及锁的拥有者的状态来决定。
它怎么做呢?线程如果自旋成功了,那么下次自旋的次数会更加多,因为虚拟机认为既然上次成功了,那么此次自旋也很有可能会再次成功,那么它就会允许自旋等待持续的次数更多。
反之,如果对于某个锁,很少有自旋能够成功的,那么在以后要或者这个锁的时候自旋的次数会减少甚至省略掉自旋过程,以免浪费处理器资源。
有了自适应自旋锁,随着程序运行和性能监控信息的不断完善,虚拟机对程序锁的状况预测会越来越准确,虚拟机会变得越来越聪明。
锁消除
消除锁是虚拟机另外一种锁的优化,这种优化更彻底,Java虚拟机在JIT编译时(可以简单理解为当某段代码即将第一次被执行时进行编译,又称即时编译).
通过对运行上下文的扫描,去除不可能存在共享资源竞争的锁,通过这种方式消除没有必要的锁,可以节省毫无意义的请求锁时间,如下StringBuffer的append是一个同步方法,但是在add方法中的StringBuffer属于一个局部变量,并且不会被其他线程所使用
因此StringBuffer不可能存在共享资源竞争的情景,JVM会自动将其锁消除。
为了保证数据的完整性,我们在进行操作时需要对这部分操作进行同步控制,但是在有些情况下,JVM检测到不可能存在共享数据竞争,这是JVM会对这些同步锁进行锁消除。
锁消除的依据是逃逸分析的数据支持。如果不存在竞争,为什么还需要加锁呢?所以锁消除可以节省毫无意义的请求锁的时间。
变量是否逃逸,对于虚拟机来说需要使用数据流分析来确定,但是对于我们程序员来说这还不清楚么?我们会在明明知道不存在数据竞争的代码块前加上同步吗?
但是有时候程序并不是我们所想的那样?我们虽然没有显示使用锁,但是我们在使用一些JDK的内置API时,如StringBuffer、Vector、HashTable等,这个时候会存在隐形的加锁操作。
比如StringBuffer的append()方法,Vector的add()方法:
COPYpublic void vectorTest(){ Vector vector = new Vector(); for(int i = 0 ; i < 10 ; i++){ vector.add(i + ""); } System.out.println(vector); }
在运行这段代码时,JVM可以明显检测到变量vector没有逃逸出方法vectorTest()之外,所以JVM可以大胆地将vector内部的加锁操作消除。
逃逸分析
如果证明一个对象不会逃逸方法外或者线程外,则可针对此变量进行优化:
同步消除synchronization Elimination,如果一个对象不会逃逸出线程,则对此变量的同步措施可消除。
重量级锁
重量级锁通过对象内部的监视器(monitor)实现,其中monitor的本质是依赖于底层操作系统的Mutex Lock实现,操作系统实现线程之间的切换需要从用户态到内核态的切换,切换成本非常高。
为什么重量级锁的开销比较大呢
原因是当系统检查到是重量级锁之后,会把等待想要获取锁的线程阻塞,被阻塞的线程不会消耗CPU,但是阻塞或者唤醒一个线程,都需要通过操作系统来实现,也就是相当于从用户态转化到内核态,而转化状态是需要消耗时间的
三种锁的区别
锁 | 优点 | 缺点 | 使用场景 |
---|---|---|---|
偏向锁 | 加锁和解锁不需要CAS,没有额外的性能消耗,和执行非同步方法相比,仅存在纳秒级的差距 | 如果线程间存在锁竞争,会带来额外的锁撤销的消耗 | 只有一个线程访问同步块或者同步方法的场景 |
轻量级锁 | 竞争的线程不会阻塞提高响应速度 | 若线程长时间抢不到锁,自旋会消耗CPU性能 | 线程交替执行同步块或者同步方法的场景 |
重量级锁 | 线程竞争不使用自旋,不消耗CPU | 线程阻塞,响应时间缓慢,在多线程下,频繁的获取释放锁,会带来巨大的性能消耗 | 追求吞吐量,同步块或者同步方法执行时间较长的场景 |
锁升级
偏向锁升级轻量级锁:当一个对象持有偏向锁,一旦第二个线程访问这个对象,如果产生竞争,偏向锁升级为轻量级锁。
轻量级锁升级重量级锁:一般两个线程对于同一个锁的操作都会错开,或者说稍微等待一下(自旋),另一个线程就会释放锁。但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁膨胀为重量级锁,重量级锁使除了拥有锁的线程以外的线程都阻塞,防止CPU空转。
锁粗化
我们知道在使用同步锁的时候,需要让同步块的作用范围尽可能小—仅在共享数据的实际作用域中才进行同步,这样做的目的是为了使需要同步的操作数量尽可能缩小,如果存在锁竞争,那么等待锁的线程也能尽快拿到锁。 在大多数的情况下,上述观点是正确的,LZ也一直坚持着这个观点。
但是如果一系列的连续加锁解锁操作,可能会导致不必要的性能损耗,所以引入锁粗话的概念。锁粗话概念比较好理解,就是将多个连续的加锁、解锁操作连接在一起,扩展成一个范围更大的锁。
如下面的例子,一个方法由两个加锁,因为num = x + y;耗时较短,对比两次锁短的多,就会锁粗化。
COPYprivate int x, y; /** * 因为一个方法需要两个加锁解锁耗费资源 * 对于 num = x + y; 耗费时间很短 就会将 * 代码包裹进去组成一个锁 * @return */ public int lockCoarsening() { int num = 0; //对象锁 synchronized (this) { x++; //todo 处理部分业务 } num = x + y; //对象锁 synchronized (this) { y++; //todo 处理部分业务 } return num; }
粗化后
COPYprivate int x, y; /** * 使用一个锁 * * @return */ public int lockCoarsening() { int num = 0; //只进行一次加锁解锁 synchronized (this) { x++; //todo 处理部分业务 num = x + y; y++; //todo 处理部分业务 } return num; }
wait和notify的原理
调用wait方法,首先会获取监视器锁,获得成功以后,会让当前线程进入等待状态进入等待队列并且释放锁。
当其他线程调用notify后,会选择从等待队列中唤醒任意一个线程,而执行完notify方法以后,并不会立马唤醒线程,原因是当前的线程仍然持有这把锁,处于等待状态的线程无法获得锁。必须要等到当前的线程执行完按monitorexit指令以后,也就是锁被释放以后,处于等待队列中的线程就可以开始竞争锁了。
wait和notify为什么需要在synchronized里面?
wait方法的语义有两个,一个是释放当前的对象锁、另一个是使得当前线程进入阻塞队列,而这些操作都和监视器是相关的,所以wait必须要获得一个监视器锁。
而对于notify来说也是一样,它是唤醒一个线程,既然要去唤醒,首先得知道它在哪里,所以就必须要找到这个对象获取到这个对象的锁,然后到这个对象的等待队列中去唤醒一个线程。
本文由
传智教育博学谷狂野架构师
教研团队发布。如果本文对您有帮助,欢迎
关注
和点赞
;如果您有任何建议也可留言评论
或私信
,您的支持是我坚持创作的动力。转载请注明出处!
-
全球百事通!为什么95%的Java程序员人,都是用不好Synchronized?
Synchronized锁优化jdk1 6对锁的实现引入了大量的优化,如自旋锁、适应性自旋锁、锁消除、锁粗化、偏向...
来源: 全球百事通!为什么95%的Java程序员人,都是用不好Synchronized?
每日时讯!Python教程:类的派生
你有“ChatGPT综合征”吗:想搞钱,或是失业焦虑?
Python教程:类的继承,什么是继承
加点广告怎么了 爱奇艺新专利可在弹幕中显示广告
环球动态:狂飙8000MHz!朗科Z RGB DDR5-8000 16GB电镀银内存图赏
每日短讯:1:1复刻仿生人手 现实版《西部世界》公司众筹开启
全球头条:5G是高铁 6G就是飞机!工信部:全面推进6G技术研发
焦点热文:公司丢货要求全体员工均摊1万赔款:新员工拒赔反被怀疑偷东西
天天观察:如何在Ubuntu上安装Nextcloud(适用于树莓派上的Ubuntu)
每日播报!Pod 进阶
每日快看:Zabbix“专家坐诊”第183期问答汇总
Spring中Bean的加载方式~
什么是Markdown
当前报道:纬德信息(688171)3月1日主力资金净买入105.72万元
旅俄大熊猫画风突变体重狂飙40公斤:摸爬滚打样样精通
百事通!特斯拉Model 2被曝成本大降37% 比丰田卡罗拉还低
世界短讯!打赢了!科比坠机照片泄露案其遗孀获赔2885万美元
天天热头条丨惊险一幕:女子用火车站自动扶梯运行李 把下面男子砸骨折
【全球速看料】玩游戏需自备爆米花:《最终幻想16》主线过场动画超11小时
当前快看:1000亿数据、30W级qps如何架构?来一个天花板案例
3-Eureka注册中心
天天精选!【验证码逆向专栏】某验三代、四代一键通过模式逆向分析
当前信息:索泰RTX 4090月白深度测试:真孤独求败!A卡没得玩了
网友晒视频广州一特斯拉在停车场连撞多车 司机下车就跑:又踩错了吗
当前看点!设计时速100公里!上海苏州互通地铁今起试跑:苏州坐地铁直达
环球资讯:韦达定理
全球播报:轻松玩转Makefile | 基础用法
医院拍CT有位患者叫熊猫 结果竟是真熊猫:网友祝福“国宝”尽快好起来
丰田拆完一辆特斯拉Model Y后被震撼了 高管惊叹:我们远远落后
全球新动态:火爆全网的AI小姐姐模型重新上线 作者:画什么图后果自负
【全球热闻】大厂年薪30万95后女生转行卖快餐:直言脱离公司KPI太快乐了
当前观察:《暗黑破坏神4》玩家打怪时 不会出现天量伤害数值
世界今热点:通用电梯:目前产能在满足履行轨道交通项目合同需求的同时,不会影响公司履行其他客户订单或新接订单的生产需求
环球报道:电脑病毒的介绍与防护_电脑病毒与防护介绍
天天日报丨浅析大促备战过程中出现的fullGc,我们能做什么?
ChunJun 1.16 Release版本即将发布,bug 捉虫活动邀您参与!
一款超级给力的弱网测试神器—Qnet(附视频)
焦点要闻:Vue,小程序开发技术详解
环球即时看!关于React-Router6 (React 路由)
每日简讯:取代马斯克:新CEO接班人浮出水面
健身网红大容量运动杯:富光1.6L顿顿桶29元发车
每日热门:马力超百匹!春风NK800双缸街车发布:46890元起
热资讯!连续三年发现大油田 渤海又出亿吨级油田:1万辆车能跑30年
粽子米泡几个小时最佳?粽子米怎么调料?
职内是什么意思?职内的职能是什么?
天天快消息!【Spring基础补充】 注解补充(二)
塑料花盆能用几年?塑料花盆和陶瓷花盆哪个养花好?
url是什么意思?url地址如何获取?
COSPLAY图赏:俄妹COS《原神》八重神子 光腿狐狸媚眼如丝
《最终幻想16》PC版稳了:将于PS5版发售后开发
2299元 小米柔风空调1.5匹开启众筹:再不怕吹空调着凉了
夜空中“最亮”的两颗星星即将“浪漫相拥”:肉眼可见
世界热资讯!一夜3次地震 全球进入地震活跃期?专家回应:其实地震一直很多
江映蓉是哪一届的超女?江映蓉那届超女前十名都有谁?
榨汁机品牌排行榜前十名有哪些?榨汁机榨果汁食谱大全
chkdsk工具访问被拒绝怎么办?chkdsk工具怎么运行?
桌面的图标有阴影怎么去掉?桌面图标怎么设置随意摆放?
windows资源管理器已停止工作是怎么回事?windows资源管理器已停止工作怎么办?
输入法哪个好用?输入法被禁用如何恢复?
2023中南大学地球科学与信息物理学院科研助理招聘(非编制)
java反射机制
世界讯息:HTML+JSP+CSS实现表格布局的例子
环球头条:周鸿祎:打造中国版ChatGPT难度比研发光刻机低很多
快看点丨中国打造全球首艘大容量电池混合动力客滚船:能充8800度电
全球最大3D内容生态!努比亚推出首款裸眼3D平板nubia Pad 3D
视讯!爽脆有嚼劲/便携小包装 鱼泉榨菜7.9元 1.2斤大促
环球新消息丨魅族20系列首发Flyme 10无界生态系统 支持全链路防诈技术
推荐系统[四]:精排-详解排序算法LTR (Learning to Rank)_ poitwise, pairwise, listwise相关评价指标,超详细知
全球热资讯!使用unplugin-auto-import自动导入插件优化vite开发vue3应用
全球视讯!移动计算入门教程_编程入门自学教程_菜鸟教程-免费教程分享
【快播报】李瑞峰回答长城:我们究竟遇到了什么问题
12.98万起 新款长城欧拉好猫上市:小姐姐最爱
世界百事通!马斯克做出重大决定:特斯拉车主可能要难受了
代表建议春节假期至9天:取消调休制度 法定3天变5天
贵州一公司设立“临时哭泣点”引热议:you cry I cry no bb
焦点快看:早安!出行气象来了(2023年3月1日)
当前短讯!读Java性能权威指南(第2版)笔记05_数据库性能JDBC
korean doll likeness模型|Japanese-doll-likeness模型获取及使用
天天微速讯:一招搞定孩子不吃饭问题
实时焦点:python通过轮子安装第三方库(以Wordcloud为例)
全球动态:能否破40亿?《流浪地球2》成2月票房冠军 力压《满江红》
代表建议春节假期延至9天 取消调休!网友期待
天天快看:兼容友商Mesh组网!中兴小方糖路由器今日开售:到手仅99元
当前头条:《流浪地球3》何时出?导演郭帆:估计还要等四年
环球微速讯:3月24日公测!暴雪《暗黑破坏神4》PC配置要求公布
每日报道:MySQL的RR和RC事务隔离级别加锁类型验证
全球今热点:白马非马是什么学派_白马非马是哪家的学说
最完美iPhone要来了!消息称iPhone 16 Pro将采用屏下Face ID
焦点速看:《白夜追凶2》要来了!优酷独家悬疑剧:前作口碑爆火
每日热文:高三女生因百日誓师热血发言表情被网暴 官方回应已心里辅导:女孩未受影响
《暗黑破坏神4》Beta测试系统需求
世界今热点:TVB小花新剧牺牲大!遭五花大绑太重口味,脚踏两只船遭雪藏半年
【全球新要闻】记一次 CesiumJS 中非 4326/3857 WMTS 数据的加载
百度预告3月16日召开发布会:主题围绕文心一言
全球信息:“假苍耳”入侵中国!剧毒杀死牛羊、改变土壤、减产60%
和AI谈恋爱之后 她忘掉了相恋5年的前男友:结局心酸
环球快看:苹果供应商印度工厂突发大火:损失超8300万!一半机器烧毁
全球关注:“春天一把豆,胜过吃猪肉”,常吃4豆,高营养高蛋白,增强免疫
快资讯丨Spring IOC官方文档学习笔记(十三)之环境概要