as this is a commonly asked (and answered) question, i'll keep it short and only answer your questions.
If you are not writing multi-threaded code, the only reason to make your code thread-safe is good practice and keeping the option to implement multithreading later open.
Sometimes, you'll use multithreading to complete a larger task that can be split into sub-tasks faster. This often requires a common variable or ressource for all of the threads to read from and write to. You'll have to give these threads a reference to the ressource they should access. Image this: You want to implement Mergesort for a huge array. Each thread is given a split of the original array to sort, but in order to put it all together, you'll need to write back to a single array. If you don't properly manage which thread writes when, things will go wrong.
Yes, in most cases, either you or a library you use will create threads. However, it is common to have asynchronous file reader libraries (reading data you want to have), where you would wait until it has finished reading before accessing the variable it is writing to.
Yes, they won't just "know" your variables and write to them with without your say-so, but sometimes, you interact with libraries by giving them a variable to write to. If the function you are using is asynchronous, be extra cautious when accessing or writing to this variable is safe.
To reassure you once again and summarize, you are correct that tread-safe design is unnecessary if you are not actively using asynchronous operations or multithreading in your app. However, for many applications, especially if you don't want to have your user interface go unresponsive during CPU-intensive tasks, asynchronous operations and multithreading can bring many benefits, if managed properly