最新要闻
- “狗狗嫌天热自己坐电梯回家”登上热搜 主人急里忙慌寻找
- 炒菜用什么油好?
- 车企卖衣服 不务正业? 焦点信息
- 微软Win11处理器要求变动:AMD、英特尔一大波新U加入支持
- 做小吃前途如何?惠记粉汤羊血加盟开店,开哪儿都火!
- 天天短讯!特斯拉车祸后复出 演员林志颖首次现身内地商演
- 专家称年轻人撑不起车市:中老年人才有足够能力拉动市场|视讯
- 今日精选:予以的拼音(予以)
- 每天喝咖啡的人 20年后都怎么样了?三大好处、三大不要 焦点精选
- 2024年见 龙芯也要做显卡了:IP设计已完成 还在优化
- 冷知识!大熊猫近视高达800度:只能看清几米之内物体 看热讯
- 索尼粉丝迷惑行为:请愿Xbox第一方游戏《星空》成PS5独占
- 开票!2023年安阳首场演唱会等你来抢!附购票入口
- 世界最新:799元价格屠夫!小米电视把国外品牌全打趴了
- 外来生物美国珍珠鳖被放生太湖:围观者欢呼雀跃|世界简讯
- 天天热讯:Mate发布Voicebox AI模型:仅需2秒片段即可“学会”语音细节
广告
手机
iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?
- 警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案
- 男子被关545天申国赔:获赔18万多 驳回精神抚慰金
- 3天内26名本土感染者,辽宁确诊人数已超安徽
- 广西柳州一男子因纠纷杀害三人后自首
- 洱海坠机4名机组人员被批准为烈士 数千干部群众悼念
家电
JUC同步锁原理源码解析五----Phaser 今日热搜
(相关资料图)
JUC同步锁原理源码解析五----Phaser
Phaser
Phaser的来源
A reusable synchronization barrier, similar in functionality to {@link java.util.concurrent.CyclicBarrier CyclicBarrier} and {@link java.util.concurrent.CountDownLatch CountDownLatch} but supporting more flexible usage.
JDK中对Phaser的定义时,一个可重用的同步栅栏。其作用相当于CyclicBarrier和CountDownLatch的结合体,但是支持更加灵活的使用
Phaser的底层实现
Phaser的底层实现依旧依赖于CAS的自旋锁操作,通过cas保证原子性的操作
2.Phaser
基本使用
import java.util.List;import java.util.concurrent.Phaser;public class PhaserDemo { void runTasks(List tasks) { final Phaser phaser = new Phaser(1); // "1" to register self // create and start threads for (final Runnable task : tasks) { phaser.register(); new Thread() { public void run() { phaser.arriveAndAwaitAdvance(); // await all creation task.run(); } }.start(); } } void startTasks(List tasks, int iterations) { Phaser phaser = new Phaser() { protected boolean onAdvance(int phase, int registeredParties) { return phase >= iterations - 1 || registeredParties == 0; } }; phaser.register(); for (Runnable task : tasks) { phaser.register(); new Thread(() -> { do { task.run(); phaser.arriveAndAwaitAdvance(); } while (!phaser.isTerminated()); }).start(); } // allow threads to proceed; don"t wait for them phaser.arriveAndDeregister(); }}
Phaser类
public class Phaser { private volatile long state;//采用long 64 位表示state变量。使用位操作来表示,cas单原子性变量保证多变量的原子性 private static final int MAX_PARTIES = 0xffff; private static final int MAX_PHASE = Integer.MAX_VALUE; private static final int PARTIES_SHIFT = 16; private static final int PHASE_SHIFT = 32; private static final int UNARRIVED_MASK = 0xffff; // to mask ints private static final long PARTIES_MASK = 0xffff0000L; // to mask longs private static final long COUNTS_MASK = 0xffffffffL; private static final long TERMINATION_BIT = 1L << 63; // some special values private static final int ONE_ARRIVAL = 1; private static final int ONE_PARTY = 1 << PARTIES_SHIFT; private static final int ONE_DEREGISTER = ONE_ARRIVAL|ONE_PARTY; private static final int EMPTY = 1; // The following unpacking methods are usually manually inlined private static int unarrivedOf(long s) { int counts = (int)s; return (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK); } private static int partiesOf(long s) { return (int)s >>> PARTIES_SHIFT; } private static int phaseOf(long s) { return (int)(s >>> PHASE_SHIFT); } private static int arrivedOf(long s) { int counts = (int)s; return (counts == EMPTY) ? 0 : (counts >>> PARTIES_SHIFT) - (counts & UNARRIVED_MASK); } /** * The parent of this phaser, or null if none */ private final Phaser parent; /** * The root of phaser tree. Equals this if not in a tree. */ private final Phaser root; /** * Heads of Treiber stacks for waiting threads. To eliminate * contention when releasing some threads while adding others, we * use two of them, alternating across even and odd phases. * Subphasers share queues with root to speed up releases. */ private final AtomicReference evenQ; private final AtomicReference oddQ;
QNode类
static final class QNode implements ForkJoinPool.ManagedBlocker { final Phaser phaser; final int phase; final boolean interruptible; final boolean timed; boolean wasInterrupted; long nanos; final long deadline; volatile Thread thread; // nulled to cancel wait QNode next; QNode(Phaser phaser, int phase, boolean interruptible, boolean timed, long nanos) { this.phaser = phaser; this.phase = phase; this.interruptible = interruptible; this.nanos = nanos; this.timed = timed; this.deadline = timed ? System.nanoTime() + nanos : 0L; thread = Thread.currentThread(); }
Phaser的构造器
public Phaser(int parties) { this(null, parties);}public Phaser(Phaser parent) { this(parent, 0);}//最终都是走这个构造器方法public Phaser(Phaser parent, int parties) { if (parties >>> PARTIES_SHIFT != 0)// throw new IllegalArgumentException("Illegal number of parties"); int phase = 0; this.parent = parent; if (parent != null) {//判断父阶段是否为空。如果有父阶段,子阶段的行为由父阶段控制,调用父阶段去处理 final Phaser root = parent.root;//root为父阶段 this.root = root; this.evenQ = root.evenQ;//使用父阶段的偶队列 this.oddQ = root.oddQ;//使用父阶段的奇队列 if (parties != 0)//如果父阶段不为空 phase = parent.doRegister(1);//将当前阶段注册到父阶段中 } else {//表示没有父阶段 this.root = this; this.evenQ = new AtomicReference(); this.oddQ = new AtomicReference(); } this.state = (parties == 0) ? (long)EMPTY : ((long)phase << PHASE_SHIFT) | //64位中高32位表示阶段数,也即phase的数量 ((long)parties << PARTIES_SHIFT) | //64位中低32位的高16位表示参与者的数量 ((long)parties);//64位中低32位的低16位表示未完成的数量}
register方法
public int register() { return doRegister(1);}private int doRegister(int registrations) { // adjustment to state long adjust = ((long)registrations << PARTIES_SHIFT) | registrations;//对当前state变量的参与数量和未完成数量都加 1 final Phaser parent = this.parent;//如果有父阶段,获取父阶段 int phase; for (;;) { long s = (parent == null) ? state : reconcileState();//拿到state的值 int counts = (int)s;//将64位取低32位的值 int parties = counts >>> PARTIES_SHIFT;//右移16位,取高16位的值,也即parties的数量 int unarrived = counts & UNARRIVED_MASK;//获取低16位的数值,也即未到达的数量 if (registrations > MAX_PARTIES - parties)//越界判断 throw new IllegalStateException(badRegister(s)); phase = (int)(s >>> PHASE_SHIFT);//获取阶段数 if (phase < 0)//阶段数为0,表示已经超过阶段数了,不需要继续处理了 break; if (counts != EMPTY) { // not 1st registration if (parent == null || reconcileState() == s) { if (unarrived == 0) // wait out advance 如果未完成数量等于0 root.internalAwaitAdvance(phase, null);//阻塞等待或者等到下一阶段推进 else if (UNSAFE.compareAndSwapLong(this, stateOffset,//将当前需要参与的数量放到state变量中 s, s + adjust)) break;//退出循环 } } else if (parent == null) {//没有父阶段或自己就是父阶段 long next = ((long)phase << PHASE_SHIFT) | adjust; //阶段数量增加 if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))//cas尝试将阶段数量增加,成功就腿很粗 break; } else { synchronized (this) { //走到这里表示,自身属于子阶段,需要接受父阶段的调度 if (state == s) { //重新检测state变量是否改变 phase = parent.doRegister(1);//向父阶段注册 if (phase < 0)//阶段数已经超过了最大阶段数 break; //while循环,设置state的中phase阶段数直至成功 while (!UNSAFE.compareAndSwapLong (this, stateOffset, s, ((long)phase << PHASE_SHIFT) | adjust)) { s = state; phase = (int)(root.state >>> PHASE_SHIFT); // assert (int)s == EMPTY; } break; } } } } return phase;}
reconcileState方法:
//只要使用在有父子阶段的存在的情况下private long reconcileState() { final Phaser root = this.root;//获取到当前阶段 long s = state;//取得当前state if (root != this) {//如果root不是当前阶段 int phase, p; // CAS to root phase with current parties, tripping unarrived while ((phase = (int)(root.state >>> PHASE_SHIFT)) != //phase等于root的阶段数 (int)(s >>> PHASE_SHIFT) &&//root的阶段数不等于当前阶段state变量的阶段数 !UNSAFE.compareAndSwapLong// (this, stateOffset, s, s = (((long)phase << PHASE_SHIFT) | //root的阶段数 ((phase < 0) ? (s & COUNTS_MASK) : //如果阶段数已经超了,直接取低32位 (((p = (int)s >>> PARTIES_SHIFT) == 0) ? EMPTY : //获取到s对应的parties数量,复制给p ((s & PARTIES_MASK) | p)))))) s = state; } return s;}
arriveAndAwaitAdvance方法
public int arriveAndAwaitAdvance() { // Specialization of doArrive+awaitAdvance eliminating some reads/paths final Phaser root = this.root;//获取当前阶段 for (;;) { long s = (root == this) ? state : reconcileState();//获取到state的状态,如果有父阶段调用reconcileState int phase = (int)(s >>> PHASE_SHIFT);//等到当前阶段数 if (phase < 0)//阶段数超了,直接返回 return phase; int counts = (int)s;//获取state的低32位 int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);//获取到未到达的参与者数量 if (unarrived <= 0)//未到达的参与者数量越界检查 throw new IllegalStateException(badArrive(s)); if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s -= ONE_ARRIVAL)) {//cas将未到达的数量减1 if (unarrived > 1)//如果未到达的数量大于1 return root.internalAwaitAdvance(phase, null);//调用父阶段控制其去睡眠等待 if (root != this)//如果this不是父阶段 return parent.arriveAndAwaitAdvance();//由父类处理,将到达线程数减1或滚动到下一阶段 long n = s & PARTIES_MASK; // base of next state//获得参与者parties数量 int nextUnarrived = (int)n >>> PARTIES_SHIFT;//获得下一个阶段参与者的数量 if (onAdvance(phase, nextUnarrived))//调用onAdvance会掉方法 n |= TERMINATION_BIT;//TERMINATION_BIT:1<<63,标识阶段数结束 else if (nextUnarrived == 0)//如果下一个阶段参与者为0 n |= EMPTY;//异或上EMPTY else n |= nextUnarrived;//否则将低32位的低16位置为下一阶段参与者的数量,表示未完成的数量等于下一个阶段参与者的数量 int nextPhase = (phase + 1) & MAX_PHASE;//获得下一个阶段的phase的数量 n |= (long)nextPhase << PHASE_SHIFT;//n异或上下一阶段phase的数量组合成state比那辆 if (!UNSAFE.compareAndSwapLong(this, stateOffset, s, n))//cas设置state变量。当前线程如果设置state变量失败,是否可以允许爆炸唤醒,不直接退出? return (int)(state >>> PHASE_SHIFT); // cas失败,返回state中的阶段数 releaseWaiters(phase);//释放等待线程 return nextPhase; } }}
internalAwaitAdvance方法
private int internalAwaitAdvance(int phase, QNode node) { // assert root == this; releaseWaiters(phase-1); // ensure old queue clean 将上一个阶段等待线程唤醒,将队列清空 boolean queued = false; // true when node is enqueued int lastUnarrived = 0; // to increase spins upon change int spins = SPINS_PER_ARRIVAL;//SPINS_PER_ARRIVAL = (NCPU < 2) ? 1 : 1 << 8,单核CPU没有自旋的必要,浪费时间 long s; int p; while ((p = (int)((s = state) >>> PHASE_SHIFT)) == phase) {//判断当前阶段数是否等于phase if (node == null) { // spinning in noninterruptible mode int unarrived = (int)s & UNARRIVED_MASK;//获取未到达的参与者数量 if (unarrived != lastUnarrived &&//未到达的参与者数量不等于lastUnarrived (lastUnarrived = unarrived) < NCPU)//lastUnarrived 赋值lastUnarrived。小于CPU的核心数,证明任务很快可以调度,值得等待。但是考虑业务线程,实际中如果CPU的核心数没有大于2,其实没有自旋的必要。 spins += SPINS_PER_ARRIVAL;//增加自旋次数 boolean interrupted = Thread.interrupted();//判断中断标志位 if (interrupted || --spins < 0) { // need node to record intr //如果中断了,或者自旋次数小于0 node = new QNode(this, phase, false, false, 0L); node.wasInterrupted = interrupted;//将中断标识赋值 } } else if (node.isReleasable()) // done or aborted 判断是否已经完成,或者说中断等方式释放 break; else if (!queued) { // push onto queue 不在队列中 AtomicReference head = (phase & 1) == 0 ? evenQ : oddQ; //根据phase的奇偶性,选择队列 QNode q = node.next = head.get();//头插法 if ((q == null || q.phase == phase) && (int)(state >>> PHASE_SHIFT) == phase) // avoid stale enq queued = head.compareAndSet(q, node); } else { try { ForkJoinPool.managedBlock(node);//由于兼容forkJoin线程池,所以这里提供模板。这里进行阻塞等待 } catch (InterruptedException ie) { node.wasInterrupted = true; } } } if (node != null) {//进入这里表示,当前阶段不一致 if (node.thread != null) node.thread = null; // avoid need for unpark() //将thread置为空 if (node.wasInterrupted && !node.interruptible) //节点被中断,并且节点不可中断 Thread.currentThread().interrupt();//重置中断标志位 if (p == phase && (p = (int)(state >>> PHASE_SHIFT)) == phase)//当前阶段数量一致,也即属于同一阶段 return abortWait(phase); // possibly clean up on abort } releaseWaiters(phase);//唤醒等待的线程 return p;}
releaseWaiters方法
private void releaseWaiters(int phase) { QNode q; // first element of queue Thread t; // its thread AtomicReference head = (phase & 1) == 0 ? evenQ : oddQ;//根据阶段数判断是奇数队列还是偶数队列 while ((q = head.get()) != null &&//获取到头结点,如果头结点补位空 q.phase != (int)(root.state >>> PHASE_SHIFT)) {//并且当前阶段数已经滚动到下一个阶段 if (head.compareAndSet(q, q.next) &&//cas替换头结点 (t = q.thread) != null) {//如果旧的头结点不为空 q.thread = null;//将节点q的线程置为空 LockSupport.unpark(t);//唤醒节点q的线程 } }}
arriveAndDeregister方法
public int arriveAndDeregister() { return doArrive(ONE_DEREGISTER);//ONE_DEREGISTER = ONE_ARRIVAL|ONE_PARTY;}
doArrive方法
private int doArrive(int adjust) { final Phaser root = this.root;//获取当前阶段 for (;;) { long s = (root == this) ? state : reconcileState();//如果有父阶段获取父阶段的state,没有取当前阶段的state int phase = (int)(s >>> PHASE_SHIFT);//获取阶段数 if (phase < 0)//如果阶段数已经小于0,表示已经结束,直接返回 return phase; int counts = (int)s;//获取state的低32位,业绩参与者和未完成的参与者 int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);//获取未到达的参与者数量EMPTY是特殊值,表示没有未到达的参与者 if (unarrived <= 0)//如果未到达的参与者小于0,非法直接抛出异常 throw new IllegalStateException(badArrive(s)); if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adjust)) {//直接cas自旋,更新state变量 if (unarrived == 1) {//如果当前线程是最后一个未完成的参与者,需要做收尾工作 long n = s & PARTIES_MASK; // base of next state 获取参与者的数量 int nextUnarrived = (int)n >>> PARTIES_SHIFT;//设置未到达的参与者数量为下一个阶段的参与者数量 if (root == this) {//如果root是当前阶段 if (onAdvance(phase, nextUnarrived))//回调钩子函数 n |= TERMINATION_BIT;//置为TERMINATION状态,TERMINATION_BIT = 1L << 63;最高位符号位表示终止标志位 else if (nextUnarrived == 0)//如果下一个阶段没有参与者 n |= EMPTY;//直接或上一个EMPTY else n |= nextUnarrived;//否则直接或上下一个阶段的未达到的参与者数量 int nextPhase = (phase + 1) & MAX_PHASE;//阶段数加1 n |= (long)nextPhase << PHASE_SHIFT;//将阶段数组合到变量n中, UNSAFE.compareAndSwapLong(this, stateOffset, s, n);//cas自旋将state置为n,表示滚动到下一个阶段 releaseWaiters(phase);//释放所有等待的节点 } else if (nextUnarrived == 0) { // propagate deregistration 这里表示root有父阶段且自己已经完成 phase = parent.doArrive(ONE_DEREGISTER);//父阶段中标识自己已经完成并且将参与者数量减1,未到达的参与者也减1 UNSAFE.compareAndSwapLong(this, stateOffset,//将当前的state,case自旋,置为EMPTY s, s | EMPTY); } else phase = parent.doArrive(ONE_ARRIVAL);//当前线程不是最后一个完成的线程,将未到达的参与者数量减1即可 } return phase; } }}
4.留言
到了这里,其实AQS的源码基本已经覆盖了,对于AQS的源码也应该有了清楚的认知。总结就是:一个volatile 的state变量,两个等待队列(竞争队列,条件队列),通过cas的方式保证单变量的原子性。后续将会对Exchanger以及Phaser进行源码解析,到此基本AQS已经到了一个段落了。后续观看源码时,请注意多考虑一下多线程并发时可能出现的情况,去理解doug lea写代码的思路。
关键词:
JUC同步锁原理源码解析五----Phaser 今日热搜
ASP.NET Core MVC 从入门到精通之日志管理_世界热闻
计算几何之两条线段的交点|世界时快讯
看点:博客项目01
“狗狗嫌天热自己坐电梯回家”登上热搜 主人急里忙慌寻找
炒菜用什么油好?
车企卖衣服 不务正业? 焦点信息
微软Win11处理器要求变动:AMD、英特尔一大波新U加入支持
InnoDB 缓冲池
天天资讯:俄罗斯天然气工业银行拟参与无担保人民币债券市场
做小吃前途如何?惠记粉汤羊血加盟开店,开哪儿都火!
天天短讯!特斯拉车祸后复出 演员林志颖首次现身内地商演
专家称年轻人撑不起车市:中老年人才有足够能力拉动市场|视讯
今日精选:予以的拼音(予以)
【财经分析】数据赋能城市升级——2023中国资源型老工业城市转型发展指数研讨会在北京举办
每天喝咖啡的人 20年后都怎么样了?三大好处、三大不要 焦点精选
2024年见 龙芯也要做显卡了:IP设计已完成 还在优化
冷知识!大熊猫近视高达800度:只能看清几米之内物体 看热讯
索尼粉丝迷惑行为:请愿Xbox第一方游戏《星空》成PS5独占
开票!2023年安阳首场演唱会等你来抢!附购票入口
Liunx nginx服务|环球要闻
Manacher算法学习笔记
世界最新:799元价格屠夫!小米电视把国外品牌全打趴了
外来生物美国珍珠鳖被放生太湖:围观者欢呼雀跃|世界简讯
天天热讯:Mate发布Voicebox AI模型:仅需2秒片段即可“学会”语音细节
全球热资讯!首发4899元 外星人新款27英寸游戏显示器上架:180Hz高刷
国产操作系统赶超Win 10 统信UOS更新:换机可批量重装软件
世界头条:因编造、传播与期货交易有关的虚假信息行为 上海点钢电子商务被罚30万元
【环球热闻】Rust语言 - 接口设计的建议之显而易见(Obvious)
天猫品牌评估一般几天_天猫品牌评估_最新消息
北京电动自行车新规今起实施:电池温度达80度需有报警音
世界新消息丨女孩毕业典礼捐10万:含4年奖学金 用于帮助乡村孩子
当前观点:高通、联发科找到共同点了:骁龙8G3、天玑9300 AI性能爆发
云南普者黑现罕见的粉白相间荷花:花瓣如脂如玉 世界快播报
ppt讲课技巧互动_ppt讲课技巧 世界视点
【解决方法】锐捷 EVE 模拟器关联 Wireshark 进行抓包 焦点速讯
js-audio-recorder 插件实现web端录音
曼努埃尔·加西亚(关于曼努埃尔·加西亚介绍)
新加坡一廉价航班飞机降落后发现少个轮胎:曾出现胎压异常
全球领先!刘经南院士:北斗是唯一集通导遥等功能卫星导航系统 新视野
民营卫星俯拍四川盆地:中国两项唯一的天府之国 全球焦点
世界关注:达标没?调查称53.7%年轻人存款不足10万 感受下中等收入群体收入标准
海口一特斯拉高速行驶撞飞小车 官方通报:致一死一伤_当前独家
英雄联盟更新不动了怎么办_英雄联盟更新不动
【解决办法】DHCP Relay环境中PC无法获取IP地址,排错与解法 全球新要闻
华为云邓明昆:云原生时代,以开源赋能数字化转型
每日视讯:Quartz.net的最佳实践
动态:【高端访谈】推进金融租赁业务“全绿”转型——专访兴业金租董事长李小东
柯力传感涨停_焦点短讯
一加Ace 2 Pro把骁龙8 Gen2下放!同档位性能无敌-全球观天下
国服关了5个月 魔兽世界音乐会重返国内:门票最高680元 世界要闻
《王者荣耀》S32赛季官宣:又一个双剑战士上线 美人鱼也要来了-每日看点
明年开播!《英雄联盟》电竞剧概念海报发布:张艺谋导演、易烊千玺主演
美国波士顿机场波音737撞上空客321:今年已发生多起类似事件_世界独家
【环球报资讯】画江湖之灵主哪里可以看完整版 画江湖之灵主哪里可以看
世界新资讯:vi命令使用详解
天天热推荐:生态合作 | ShowMeBug入驻集简云平台,多招聘系统管理更便捷
ElasticSearch的使用和介绍
CVE-2023-33246命令执行复现分析 环球观天下
java~搞懂Comparable接口的compareTo方法_天天观焦点
贵州“村超”持续火爆 游客纷纷点赞榕江美食_视讯
天天速读:华为在东莞成立极目机器人公司 注册资本为8.7亿元
不叫C929 中国商飞展出最新宽体远程飞机:载320人飞1.2万公里-当前焦点
官方:国家反诈中心App累计预警3.1亿次 96110电话一定要接!
十几万买豪车将成历史?BBA集体宣布放弃低端车型
最具颠覆性技术 马斯克再次警告:AI有可能给人类带来灾难-每日资讯
全球热门:《塞尔达传说王国之泪》5月份在日本售出150万部
每日报道:使用Flow发送企业应用的通知到微信里
.Net 微服务之旅 天天播报
华为云黄瑾:做强坚实数据底座,GaussDB与产业携手共进
度假区(张渚镇)现场检查国家卫生镇复审工作开展情况
天天快播:华为要求日本通信企业支付专利费 揭秘背后:WiFi 6等专利简直无敌
8月上市!110万的仰望U8要收取豪车税和购置税吗:官方给出答案|世界聚看点
小米系造车成果申报了!增程式越野、智能驾驶拉满:乍看很路虎卫士 环球热讯
《黑袍纠察队》父亲节贺图:祖国人化身"好大儿"-世界热推荐
环球简讯:安卓用户为何加速转投iPhone?原因揭开
每日信息:用电负荷频创新高 央企能源保供备战“迎峰度夏”
中兴通讯(000063):中兴闪耀400G与算力网络时代|全球热消息
环球快看点丨《三体》番外剧《三体:大史》新海报出炉:于和伟主演
关于Cloud-磁盘-分区-物理边界的扩展-扩容
*ST易尚:减持是高管个人权利 公司正准备提交退市复核申请 世界热闻
市区真的能开?小鹏首款MPV曝光 车长5.45米 比腾势D9还大
天天速读:深圳龙华暴雨内涝 街头水深没过车头 比亚迪唐淡定冲浪
成本价曝光!日媒拆小米12T Pro:对中国自研芯片现状感叹 华为笑而不语
世界消息!产品未出周边先行!MOMAX宣布将为Vision Pro开发系列配件
月底全量推送!阿维塔AVP代客泊车有多强:实测逆天|当前速读
中国最富的50个城市——哪里最富?-环球报资讯
焦点热议:Writing for Engineers(作为工程师应该如何写作) —— Stemwede
全球今亮点!强化学习从基础到进阶-案例与实践[1]:强化学习概述、序列决策、动作空间定义、策略价值函数、探索与利用、Gym强化学习实验
【快播报】更好发挥货币政策效能
大获全胜!小米618终极战报来了:卖了194亿、满眼全是第一 天天热资讯
焦点要闻:智能手表鼻祖Pebble复活!推出全新Pebble Cosmos Vogue手表
2023年 为什么住大平层的人迫切想换台电视?
天天通讯!女子买蛋糕遇“空心包装刺客”:神似铜火锅被网友吐槽
江苏省高校辅导员和大学生先进典型颁奖典礼在宁举行
一文读懂ChatGPT的工作原理:大语言模型是个啥?它到底咋工作的? 环球聚焦
世界动态:MySQL中SQL语句的执行顺序(详细)
海外交友源码平台搭建:基础功能的实现(一)
推动戏剧事业高质量发展
售价8.99万元起 钇为3全球上市 重新定义纯电A级车|热讯