On Apple platforms, JSONDecoder relies on JSONSerialization for its initial parsing, and then creates a fresh __JSONDecoder (internal class) to actually do the decoding. It passes an _Options, which is a struct, so that's copied. So there shouldn't be any interaction at all between the threads as long as you're not changing the options (which is not thread-safe).
So it's probably slightly cheaper to reuse the same decoder, since it avoids allocating and deallocating a class instance, which is usually a win over just retaining and releasing a class instance (and I would expect that to be the case here). But I would expect the difference to be very, very small compared to the much larger cost of JSON decoding.
In fact, if I had a situation where this were actually worth profiling (and you would need to profile it to know if it's faster or not), I'd be asking "why in the world am I decoding this many different JSON messages this quickly?" For this to matter, the JSON probably wouldn't be coming from the network or disk (those are so insanely slow to make one extra class allocation meaningless). It would only matter if you were working JSON that is already in memory in huge numbers of small messages. And in that case, the answer would almost certainly be "stop using JSON for that problem."
But I expect that in almost all cases, this just doesn't matter, and I definitely would not proactively optimize it. Implement whichever is clearer in your code. Then profile the code to see where your bottlenecks are.