在 Cadence/Temporal 工作流程编程中:
- 不允许使用本机线程库。例如,在 Java 中,线程必须通过
Async.procedure
or创建,Async.function
而在 Golang 中,线程必须通过workflow.Go
. 所以为什么? - 有没有像使用本机线程这样的赛车条件?例如
Hashtable
,还是ConcurrentHashMap
应该用来代替HashMap
线程安全?
在 Cadence/Temporal 工作流程编程中:
Async.procedure
or创建,Async.function
而在 Golang 中,线程必须通过workflow.Go
. 所以为什么?Hashtable
,还是ConcurrentHashMap
应该用来代替HashMap
线程安全?工作流执行必须是确定性的。这是历史回放重建线程状态所必需的。为了具有确定性,Cadence/Temporal 以协作的方式控制线程调度(而不是像大多数操作系统那样抢占式):
所以:
HashMap
在工作流代码中使用是安全的。Cadence/Temporal SDK 有一个 DeterministicRunner 来操纵线程执行。例如Java SDK、Golang SDK。这个确定性的运行器将决定以正确的顺序运行哪个工作流线程,并且一次运行一个。对于每个决策任务,它将循环执行,直到“所有线程都被阻塞”——RunUntilAllBlocked/ExecuteUntilAllBlocked。
Async.procedure
//会创建一个新线程并添加到deterministicRunnerAsync.function
中workflow.Go
的列表中,这样执行就会受到控制。
因为任何时候只能执行一个线程,所以我们在常规代码中遇到的大多数竞速情况都不会发生。
但是,这并不意味着根本没有比赛条件。在某些情况下,仍然会有条件导致一些死锁。
换句话说,合作并不意味着没有比赛条件或僵局。这只是意味着死锁情况要少得多。并且没有像抢占式线程调度那样导致脏读的竞争条件。
如果threadA抢到lockA并等待一个activity,那么它让给threadB,然后threadB抢到lockB并等待一个activity;
Activity结束后,threadA会在释放lockA之前尝试获取lockB,threadB会在释放lockA之前尝试获取lockA;
现在,当活动完成时,它们将陷入僵局。
https://community.temporal.io/t/how-does-workflow-thread-synchronization-work/504