I am trying to write threaded code for the following calculation:

given an opaque object x, and indices i, calculate y_i = g(x, i),

given each y_i and indices j, calculate {z_i}_j = h(x, y_i, j),

reduce all the z's with a bivariate function r, which is commutative and associative.
Here is the singlethreaded MWE, I would appreciate some help with making this multithreaded.
### elements of the the calculation
g(x, i) = (; x, i) # y_i = g(x, i)
function h(x, g_xi, j) # z_i_j = h(x, g(x, i), j)
(; i) = g_xi
sleep(rand() / 100)
Dict((x, i, j) => "$(i)_$(j)")
end
r(a, b) = merge(a, b) # merge z_i_j
# singlethreaded implementation
function single_threaded(g, h, r, x, all_i, all_j)
function inner(i)
g_xi = g(x, i)
mapreduce(j > h(x, g_xi, j), r, all_j)
end
mapreduce(inner, r, all_i)
end
# example
ALL_I = 1970:1980
ALL_J = 1:24
single = single_threaded(g, h, r, nothing, ALL_I, ALL_J)