# How does workflow thread synchronization work?

**URL:** <https://community.temporal.io/t/how-does-workflow-thread-synchronization-work/504>\
**Category:** Community Support\
**Tags:** java-sdk, signals\
**Created:** [August 21, 2020, 5:43pm UTC](https://community.temporal.io/t/how-does-workflow-thread-synchronization-work/504 "2020-08-21T17:43:30Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![artem](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/artem/32/154_2.png) [@artem](https://community.temporal.io/u/artem)\
**Post date:** [August 21, 2020, 5:43pm UTC](https://community.temporal.io/t/how-does-workflow-thread-synchronization-work/504/1 "2020-08-21T17:43:30Z")

</div>

Hello,

Documentation says `There is no need in explicit synchronization because multi-threaded code inside a workflow is executed one thread at a time and under a global lock.`

There is also the following documentation in DeterministicRunner.java:

```auto
/**
   * Executes a runnable in a specially created workflow thread. This newly created thread is given
   * chance to run before any other existing threads. This is used to ensure that some operations
   * (like signal callbacks) are executed before all other threads which is important to guarantee
   * their processing even if they were received after workflow code decided to complete. To be
   * called before runUntilAllBlocked.
   */
  void executeInWorkflowThread(String name, Runnable r);

```

With this code:

```auto
private final List<Object> jobQueue = new ArrayList<>();

@WorkflowMethod
@Override
public void executeCreateTree(@Nonnull List<Object> jobQueue) {
    this.jobQueue.addAll(jobQueue.getJobsList());

    Workflow.await(() -> this.jobQueue.size() > 0);

    Object jobToExecute = this.jobQueue.get(0);
    this.jobQueue.remove(0);

    if (this.jobQueue.size() > 0) {
        Workflow.continueAsNew(this.jobQueue);
    } else {
        // Exit workflow
    }
}

@Override
@SignalMethod
public void scheduleCreateTree(@Nonnull Object jobInfo) {
    this.jobQueue.add(jobInfo);
}

```

How does Temporal Java SDK guarantee that jobQueue did not change between `this.jobQueue.size() > 0` and `Workflow.continueAsNew(this.jobQueue);` lines? DeterministicRunner documentation indicates that SignalMethod will be given a chance to run before workflow completes. And that would indicate that last signal could be lost as workflow would decide to exit.

In general it is possible for thread to be interrupted in between those 2 lines. In a typical java application I would put both if-clause and Workflow.continuesAsNew inside of a single critical section. But it seems to be not recommended here.

Could you please advise?

---

<div class="post-metadata">

**Author:** ![maxim](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/maxim/32/8_2.png) [@maxim](https://community.temporal.io/u/maxim)\
**Post date:** [August 21, 2020, 5:55pm UTC](https://community.temporal.io/t/how-does-workflow-thread-synchronization-work/504/2 "2020-08-21T17:55:23Z")

</div>

> How does Temporal Java SDK guarantee that jobQueue did not change between `this.jobQueue.size() > 0` and `Workflow.continueAsNew(this.jobQueue);` lines? DeterministicRunner documentation indicates that SignalMethod will be given a chance to run before workflow completes. And that would indicate that last signal could be lost as workflow would decide to exit.

Temporal uses cooperative multithreading to provide this guarantee as well as ensure deterministic execution of multithreaded code. Only one thread is executed at a time and switch to another thread can happen only when a blocking operation using Temporal provided primitives is called. Examples of such operations are `Workflow.sleep`, `Promise.get`, `Workflow.await`. As no blocking operations are called between `this.jobQueue.size() > 0` and `Workflow.continueAsNew(this.jobQueue);` lines, no other thread can intervene.

> In general it is possible for thread to be interrupted in between those 2 lines. In a typical java application I would put both if-clause and Workflow.continuesAsNew inside of a single critical section. But it seems to be not recommended here.

It is not recommended as standard Java synchronization can block threads in places that Temporal doesn’t have control over. It leads to deadlocks. [Here is an issue](https://github.com/temporalio/java-sdk/issues/28) to add a deadlock detector to make troubleshooting such programming mistakes easier.

---

<div class="post-metadata">

**Author:** ![artem](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/artem/32/154_2.png) [@artem](https://community.temporal.io/u/artem)\
**Post date:** [August 21, 2020, 6:05pm UTC](https://community.temporal.io/t/how-does-workflow-thread-synchronization-work/504/3 "2020-08-21T18:05:18Z")

</div>

Cool, thank you very much.

---

<div class="post-metadata">

**Author:** ![qlong](https://sea2.discourse-cdn.com/flex016/user_avatar/community.temporal.io/qlong/32/266_2.png) [@qlong](https://community.temporal.io/u/qlong)\
**Post date:** [March 4, 2022, 8:02pm UTC](https://community.temporal.io/t/how-does-workflow-thread-synchronization-work/504/4 "2022-03-04T20:02:40Z")

</div>

I am trying to summarize my learning here: [How does multi-threading works in Cadence/Temporal workflow? - Stack Overflow](https://stackoverflow.com/questions/71356668/how-does-multi-threading-works-in-cadence-temporal-workflow/71356669#71356669)
