C++ thread safe queue implementation
Your concerns are correct. The std::notify_one description says that


  Even if the shared variable is atomic, it must be modified under the mutex in order to correctly publish the modification to the waiting thread.




Code wise, return true/return false usually indicate a room for improvement. What you are actually returning is a state of _shutdown. Do it explicitly:

        if (!shutdown) {
            dequeue item;
        }
        return !_shutdown;


You may also notice that shutdown is always tested with negation. It indicates that the semantics is reversed. I recommend to replace shutdown with something like keep_running.