The deep binding approach will not work correctly with multithreading any more correctly than shallow binding, if there is only one such stack, or any shared state whatsoever that is not atomically manipulated.
It will work if there is a spaghetti stack. So that is to say, each thread extends the dynamic environment with a newly allocated frame that points upward to the parent environment.
Each thread needs a thread-specific pointer to the top of its own dynamic environment chain.
I'm not sure what you think is the important difference between these implementations?
'Dynamic binding' is an abstract concept. The abstract concept is a global variable with a stack of values. How you implement it and whether you share the call-stack instead of a separate stack is is up to you. It's still the same dynamic scoping.
Only one of them works with multiple threads. Dynamic scoping based on save-and-restore of symbol value slots is completely incompatible with multithreading. That's why Emacs still doesn't have threads.
It will work if there is a spaghetti stack. So that is to say, each thread extends the dynamic environment with a newly allocated frame that points upward to the parent environment.
Each thread needs a thread-specific pointer to the top of its own dynamic environment chain.