问题:
如题,今天遇到有人问,新建一个线程操作页面数据不生效,第一次遇到这种实现,于是自己在本地试了下。
先说结论:新建线程操作model和view对象修改页面是不可行的
实现:
接下来讲下过程:
自己本地写了最简单的代码来复现,代码如下:
在页面数据绑定之前,新建一个线程执行task任务。
task任务类,构造的时候传入formView对象,然后run方法执行测试的业务逻辑。这里给view页面的单据体增加一行数据。
转折:
上述代码发现,竟然是可以执行成功的。线程里面的逻辑在页面上出现了,我就不以为然的反馈给该同事,这个方案是可行的。但是该同事本地的逻辑是不成功的,他就自己又试了下,代码改成了如下的逻辑,发现不行了:
思考:
根据上述代码,仔细思考下,view对象的生命周期,感觉是请求响应回去就会销毁,但是不重要,因为页面没关闭的话,可以根据pageId构造view对象。然后想到,主线程执行完成之后,请求就会响应回去,响应包括view、model对象等信息。此时如果子线程里面的逻辑没有执行完成,没有对model进行修改的话,就不会呈现效果。然后子线程对model修改完成之后,因为tcp连接已经结束,后台也没办法主动和前端建立连接(你要用什么webSocket啥的也不是不行),没办法通知到前端去执行指令,所以方案是不可行的。
结果:
于是最终验证下。代码让子线程睡3秒,执行业务逻辑处打断点。f12看下页面请求的响应,发现页面响应完成,还没进断点,验证我们的推测是正确的。
注意事项:
1.不要打断点的方式去调试多线程的问题,我深受其害。因为如果主线程还没执行完成的时候,cpu可能会执行子线程,当子线程进入断点的时候会卡住jvm主线程的执行,导致请求阻塞不能响应。(细节比较复杂,有兴趣的了解下断点原理)
参考资料:
推荐阅读