# ReentrantLock: generate once, or every time before \`for\`

**URL:** https://discourse.julialang.org/t/reentrantlock-generate-once-or-every-time-before-for/130965
**Category:** General Usage
**Tags:** question, parallel
**Created:** [July 23, 2025, 7:03am UTC](https://discourse.julialang.org/t/reentrantlock-generate-once-or-every-time-before-for/130965 "2025-07-23T07:03:37Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)
#### Post date: [July 23, 2025, 7:03am UTC](https://discourse.julialang.org/t/reentrantlock-generate-once-or-every-time-before-for/130965/1 "2025-07-23T07:03:37Z")

</div>

I learnt about `ReentrantLock` in JuMP’s [doc](https://jump.dev/JuMP.jl/stable/tutorials/algorithms/parallelism/#Example:-building-data-structures-in-parallel).

```julia
function a_correct_way_to_build_with_multithreading()
           model = Model()
           @variable(model, x[1:10])
           my_lock = Threads.ReentrantLock()
           Threads.@threads for i in 1:10
               con = @build_constraint(x[i] <= i)
               Threads.lock(my_lock) do
                   add_constraint(model, con)
               end
           end
           return model
       end

```

This example reveals some idea, but it is not thorough. Therefore I have a question.

- is this line `my_lock = Threads.ReentrantLock()` a **one-off** operation, or should we write it **every time** immediately before `Threads.@threads for i in 1:10`?

Take a simpler analogous example. This is a **one-off** case

```julia
container = Vector{Int}(undef, 3) # one-off is enough
while true
    # here we don't need to allocate container once more
    # we also don't need to reset some state, because they are irrelevant
    Threads.@threads for i in 1:3
        container[i] = i
    end
end

```

This is a case we must execute **every time** before `for`

```julia
flag = falses(3) # allocate
flag .= false # reset the state
while true
    flag .= false # we must reset the state
    Threads.@threads for i in 1:3
        if flag[i] == false
            flag[i] = true
        else
            error()
        end
    end
end

```

---

<div class="post-metadata">

### Author: ![WalterMadelim](https://avatars.discourse-cdn.com/v4/letter/w/3e96dc/32.png) [@WalterMadelim](https://discourse.julialang.org/u/WalterMadelim)
#### Post date: [July 23, 2025, 10:46am UTC](https://discourse.julialang.org/t/reentrantlock-generate-once-or-every-time-before-for/130965/2 "2025-07-23T10:46:14Z")

</div>

It appears that we only need to acquire `my_lock` one-off.  
Here is a simple test I don’t know whether it is appropriate

```julia
my_lock = Threads.ReentrantLock(); # acquire it only once
std_ans = sum(1:1000000);
for i = 1:100 # test 100 times
    s = 0
    Threads.@threads for i = 1:1000000
        Threads.lock(my_lock) do # reuse it multiple times
            s += i
        end
    end
    s == std_ans || error()
end
# No ERROR can be seen, my might infer `my_lock` works properly

```

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [July 23, 2025, 12:14pm UTC](https://discourse.julialang.org/t/reentrantlock-generate-once-or-every-time-before-for/130965/3 "2025-07-23T12:14:00Z")

</div>

Ive moved this out of the optimization category because it isnt specific to JuMP. I suggest you look up the Julia documentation for threading and locks, or any computer science text. This isnt a topic specific to Julia.

---

<div class="post-metadata">

### Author: ![sgaure](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sgaure/32/14779_2.png) [@sgaure](https://discourse.julialang.org/u/sgaure)
#### Post date: [July 23, 2025, 1:24pm UTC](https://discourse.julialang.org/t/reentrantlock-generate-once-or-every-time-before-for/130965/4 "2025-07-23T13:24:38Z")

</div>

> [@WalterMadelim](#):
>
> It appears that we only need to acquire `my_lock` one-off.  
> Here is a simple test I don’t know whether it is appropriate

This is correct. A lock is just a struct. You may create it as global `const`, or just before the loop. The only requirement is that all the tasks that use it for synchronization uses the same instance. Creating a lock is a very lightweight operation (it’s just a struct, no complicated setup), so for clarity you should perhaps create it just prior to where you use it. However, it’s a mutable struct, so memory is allocated for it.
