The documentation for both OhMyThreads.jl and ChunkSplitters.jl do a great job at explaining how “simple” multithreading can work.
As an example, using ChunkSplitters.jl, you could do:
# setup
n = Threads.nthreads()
ds = mutable_datastructure()
dss = [deepcopy(ds) for _ in 1:n]
outputs = zeros(length(some_iterable))
Threads.@threads for (i, c) in enumerate(chunks(some_iterable; n=n))
local ds = dss[i]
for j in c
outputs[j] = computation!(ds, j)
end
end