html制作祐康物流系统,基于 HTML5 WebGL 的医疗物流系统

favicon.ico摘要:

nArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)i

前言

物联网( IoT ),简单的理解就是物体之间通过互联网进行链接。世界上的万事万物,都可以通过数据的改变进行智能化管理。ioT 的兴起在医疗行业中具有拯救生命的潜在作用。

不断的收集用户信息并且实时的进行诊断,所以未来 iot 肯定在医疗行业的应用会呈覆盖性。下面是我最近做的一个医疗物流系统,用来观察医疗物流过程。

解决原子性问题原子性问题的源头就是线程切换,但在多核CPU的大背景下,不允许线程切换是不可能的,正所谓「魔高一尺,道高一丈」,新规矩来了:互斥:同一时刻只有一个线程执行实际上,上面这句话的意思是:对共

27d87489478e7335dcd1cf132d1c072e.gif

实现过程

增加光源

整个原场景其实是非常暗的,所以需要使用灯光的效果照亮整个场景,使其接近真实世界的场景。

ht.Default.startAnim({duration:config.orbitalP?2000:(medicalKitLevel===0&&elevatorIndex==3?7

我们看下对比。

上面程序的模型展示:这里我们锁的是this,可以保护this.count。但有些同学认为getCount方法没必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上sy

f6a7441b-3aa1-4b6f-a20a-8e79edde75e8.jpg

light的一些属性:

type代表灯光的类型

color代表灯光的颜色

intensity代表灯光的强度(1是最大值)

range代表范围

addLight() {

const skyBox= this.dm.getDataByTag("skyBox")//限制视野在天空球之内

this.gv.setSkyBox(skyBox)

const light= newht.Light()const lightSource= this.dm.getDataByTag("sunlight").p3()const config={"light.type": "point","light.color": "white","light.intensity": 0.3,"light.range": 10000}

light.s(config)

light.p3(lightSource)this.dm.add(light)

}

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

看向物体

看到左下角的一个小窗口,其实是另一个3d场景,把它定位到左下角的,两个场景都使用了反序列化( deserialize)。

349f6d03-d6b5-42de-b0ea-3cb6293973f9.jpg

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

因为要定位医疗箱移动,所以这里使用到了 flyTo方法 。

var renderCanvas = function(medical, duration) {

ht.Default.startAnim({

duration,

easing(v, t) {returnt

},

action(v, t) {

outScreenG3d.flyTo(medical, { direction: [-5, 3, 5], distance: 300})

}

})

}

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

封装动画

如果要实现这么多的动画,首先想到的是一个个物体进行移动的过程。医疗箱的行走、电梯的升降、传送带运送医疗箱等我们都可以对他们的动作进行封装。

个个物体进行移动的过程。医疗箱的行走、电梯的升降、传送带运送医疗箱等我们都可以对他们的动作进行封装。如图可以看到医疗箱总是在动,所以定义了一个行走的动画,每次医疗箱行走的距离、行走方向、动画的配置都进

如图可以看到医疗箱总是在动,所以定义了一个行走的动画,每次医疗箱行走的距离、行走方向、动画的配置都进行传参。

mation1",null); 总结 做完这个demo之后,除了对 HTforWeb 更加熟练之外,对物联网也有了更深刻的概念。 我身为一名前端工作者

这里要说明的参数:

尺,道高一丈」,新规矩来了:互斥:同一时刻只有一个线程执行实际上,上面这句话的意思是:对共享变量的修改是互斥的,也就是说线程A修改共享变量时其他线程不能修改,这就不存在操作被打断的问题了,那么如何实现

个场景,使其接近真实世界的场景。 我们看下对比。light 的一些属性:type 代表灯光的类型color 代表灯光的颜色intensity 代表灯光

1.node(对应的元素)

2.fn(动画执行完进行回调的函数)

3.config(动画配置)

4.coord(方向轴)

//行走动画

walkAnim(node, fn, config, coord) {

const { duration, space }=config

const positionArray=node.p3()

let isShadow= falselet ShadowNode= null

//如果移动的元素是icu车或者供应车的话 获取它的阴影跟随元素移动

if (node.getTag() === "supply" || node.getTag() === "icuCar") {

isShadow= trueShadowNode= this.dm.getDataByTag(`${node.getTag()}Shadow`)

}

ht.Default.startAnim({

duration,

easing:function(t) {returnt

},

action(v, t) {if (coord === "x") {

node.p3(positionArray[0] + t * space, positionArray[1], positionArray[2])

isShadow&& ShadowNode.p3(positionArray[0] + t * space, positionArray[1], positionArray[2])

}else if (coord === "y") {

node.p3(positionArray[0], positionArray[1] + t * space, positionArray[2])

isShadow&& ShadowNode.p3(positionArray[0], positionArray[1] + t * space, positionArray[2])

}else{

node.p3(positionArray[0], positionArray[1], positionArray[2] + t *space)

isShadow&& ShadowNode.p3(positionArray[0], positionArray[1], positionArray[2] + t *space)

}

},

finishFunc() {typeof fn === "function" &&fn(node)

}

})

}

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

物体之间的影响

电梯的升降会影响很多东西,比如频台的移动会带着传送带和医疗箱,这里我用到了 sethost 吸附方法(吸附:节点指定宿主,宿主进行改变会影响节点)。

很多场景下非常合适,我需要电梯升降的过程中带用医疗箱和频台一起上升,还有医疗箱放到传送带的时候,医疗箱要动起来,感觉是这真的传送带在带动医疗箱进行运动。

nized锁举例来说明如何解决原子性问题,主要是帮助大家建立宏观的理念,用于解决原子性问题,这样后续你看到无论什么锁,只要脑海中回想起本节说明的模型,你会发现都是换汤不换药,学习起来就非常轻松了.到这

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

这里要说明的参数:

尺,道高一丈」,新规矩来了:互斥:同一时刻只有一个线程执行实际上,上面这句话的意思是:对共享变量的修改是互斥的,也就是说线程A修改共享变量时其他线程不能修改,这就不存在操作被打断的问题了,那么如何实现

个场景,使其接近真实世界的场景。 我们看下对比。light 的一些属性:type 代表灯光的类型color 代表灯光的颜色intensity 代表灯光

1.node(操作的电梯元素)

2.medicalKit(医疗箱)

3.fn(动画执行完进行回调的函数)

4.status (电梯上升和下降的状态)

5.config(动画配置)

//电梯升降动画

elevatorAnim(node, medicalKit, fn, status, config) {

const self= this

//获取电梯的index 让对应的频台也跟着动

const elevatorIndex = node.getTag().replace(/[^0-9]/ig, "") - 0

//获取医疗箱的index 控制电梯升降的距离

const medicalKitIndex = medicalKit.getTag().replace(/[^0-9]/ig, "") - 0const positionArray=node.p3()

const station=self.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主

station.setHost(node)

medicalKit.setHost(node)//设置升降状态

if (elevatorIndex === 3) self.elevatorRunning = true

//升降距离 status 为 0 的时候是下降 最低部位的距离是固定的 所以只需要控制上升的距离

const medicalKitLevel =self.returnMedicalKitLevel(medicalKitIndex)//电梯的属性

//最低点的位置 Lowest

//如果有轨道的话 就去轨道的位置 否则就按照层数 orbitalP

//第一层的位置 distance

let space

const addSpace= medicalKitIndex === 7 ? 100 : 0

if (status == 1) {

space= config.orbitalP ? config.orbitalP : config.distance + addSpace + (400 *medicalKitLevel)

}else{

space=config.Lowest

}//下降状态时 医疗箱不会做动作

if (status === 0) {

medicalKit.setHost()

}returnht.Default.startAnim({

duration: config.orbitalP? 2000 : (medicalKitLevel === 0 && elevatorIndex == 3 ? 700 : 2500 + (medicalKitLevel * 1000)),

action(v, t) {

node.p3(

positionArray[0],

positionArray[1] + ((space - positionArray[1]) *t),

positionArray[2]

)

},

finishFunc() {

station.setHost()typeof fn === "function" &&fn(node)

}

})

}

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

动画暂停

动画的过程中有个问题需要处理就是等待电梯的动画,医疗箱在动画过程中,需要判断电梯是否在上升,如果不在地面的话,需要等待。

config){constself=this//获取电梯的index让对应的频台也跟着动constelevatorIndex=node.getTag().replace(/[^0-9]/ig,'

4a3bb0d5-1f3d-465c-9bc9-ce9e338070b9.jpg

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

我的思路是,当医疗箱走到离电梯一点距离的时候,需要判断电梯是否在上升状态,如果是的话,需要调用动画暂停的方法。

medicalKit.getTag().replace(/[^0-9]/ig,"")-0constpositionArray=node.p3()conststation=self.dm

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

当elevatorRunning 为false 的时候代表电梯没有运动,否则在运动中。

电梯动画开始的时候设置为 true,结束后设置变量为 false,  就可以监控它的状态了。

n.setHost(node)medicalKit.setHost(node)//设置升降状态if(elevatorIndex===3)self.elevatorRunning=true//升降距离s

ht.Default.startAnim 方法会返回一个实例,通过实例的方法可以对当前动画进行一些操作。

const anim =ht.Default.startAnim({

duration,

action(v, t) {

node.p3(

positionArray[0],

positionArray[1],

positionArray[2] - (tpMax - positionArray[2]) *t

);if (index > 1 && self.elevatorRunning === true) {if (node.p3()[2] <=stopMax) {

anim.pause();

const t= setInterval(() =>{if (self.elevatorRunning === false) {

anim.resume();

clearInterval(t);

}

},100);

}

}

},

finishFunc() {typeof fn === "function" &&fn();

}

});return anim;

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

事件监听(发布、订阅)

因为需要监听某个当前动画的结束,然后进行相机位移。

,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容后,你会发现无论是隐式锁/内置锁(synchronized)还是显示锁(Lock)的使用都是在找寻这种关系,关系

如图,我需要监听第一个 3d 场景中显示提示文字动画结束,然后执行第二个 3d 场景的显示。因为2个是不同的场景,是不能用回调的方法监听到的,所以这里就用到了eventBus 事件总线。

6a4dc9bb-264c-4536-8166-20df8a8cba99.jpg

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

ult.startAnim({duration,action(v,t){node.p3(positionArray[0],positionArray[1],positionArray[2]-(tpMa

rivateintcount;publicsynchronizedvoidbadSync(){//其他与共享变量count无关的业务逻辑count++;}publicvoidgoodSync(){//

])}else{node.p3(positionArray[0],positionArray[1],positionArray[2]+t*space)isShadow&&ShadowN

静态同步方法,锁的是当前类的Class对象,如ThreeSync.class对于同步方法块,锁的是synchronized括号内的对象我特意在三种synchronized代码里面添加了「临界区」字样的

.p3(positionArray[0],positionArray[1]+t*space,positionArray[2])isShadow&&ShadowNode.p3(posit

和没必要保护的非共享变量一起保护起来了,举两个例子来说你就明白这么做的坏处了编写串行程序时,是不建议try...catch整个方法的,这样如果出现问是很难定位的,道理一样,我们要用锁精确的锁住我们要保

icsynchronizedvoidstaticSyncMethod(){//临界区}publicvoidsyncBlockMethod(){synchronized(object){//临界区}}}

onArray[1],positionArray[2])isShadow&&ShadowNode.p3(positionArray[0]+t*space,positionArray[1

必要加synchronized关键字,因为是读的操作,不会对共享变量做修改,如果不加上synchronized关键字,就违背了我们上一篇文章happens-before规则中的监视器锁规则:对一个锁的

icalKitLevel)}else{space=config.Lowest}//下降状态时医疗箱不会做动作if(status===0){medicalKit.setHost()}returnht.D

s.dm.getDataByTag("skyBox")//限制视野在天空球之内this.gv.setSkyBox(skyBox)constlight=newht.Light()cons

」字样的注释,那什么是临界区呢?临界区:我们把需要互斥执行的代码看成为临界区说到这里,和大家串的知识都是表层认知,如何用锁保护有效的临界区才是关键,这直接关系到你是否会写出并发的bug,了解过本章内容

我们要保护的资源就够了,其他无意义的资源是不要锁的锁保护的东西越多,临界区就越大,一个线程从走入临界区到走出临界区的时间就越长,这就让其他线程等待的时间越久,这样并发的效率就有所下降,其实这是涉及到锁

f.dm.getDataByTag(`station${elevatorIndex}`)//吸附宿主station.setHost(node)medicalKit.setHost(node)//设置升

效工具汇总|回复「工具」面试问题分析与解答技术资料领取|回复「资料」以读侦探小说思维轻松趣味学习Java技术栈相关知识,本着将复杂问题简单化,抽象问题具体化和图形化原则逐步分解技术问题,技术持续更新,

成功,则进入临界区(对共享变量进行修改),持有锁的线程执行完临界区代码后,执行unlock(),释放锁。针对这个模型,大家经常用抢占厕所坑位来形容:在学习Java早期我就是这样记忆与理解锁的,但落实到

下面是 eventBus 的使用,第一个参数代表要监听的注册函数名,第二个是回调函数。

//事件总线 监听事件

eventbus.on("animation1", _ =>{

const medical= dm.getDataByTag("medicalKit1")

renderView(medical, dm, gv)

})

下面是 eventBus发射的使用,第一个参数代表要触发的函数名,第二个是发射给函数的参数。

//触发事件

eventbus.emit("animation1", null);

总结

做完这个 demo 之后,除了对 HT for Web 更加熟练之外,对物联网也有了更深刻的概念。

etSkyBox(skyBox)constlight=newht.Light()constlightSource=this.dm.getDataByTag("sunlight").p3

我身为一名前端工作者,在这个时代感觉非常的自豪,因为我能通过自己的技能创造出许多能造福和改善人们生活的东西。

levatorRunning===true){if(node.p3()[2]<=stopMax){anim.pause();constt=setInterval(()=>{if(self.

希望大家看到我的 demo 能够得到一些启发,同时也要相信自己能够创造不可能,为社会做出贡献。

什么锁,只要脑海中回想起本节说明的模型,你会发现都是换汤不换药,学习起来就非常轻松了.到这里并发的三大问题有序性,可见性,原子性都有了解决方案,这是远看并发,让大家有了宏观的概念;但面试和实战都是讲求

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值