(Unlike other answers) a security contract is documented : look in the javaadocs interface (as opposed to javadoc methods). For example, at the bottom of the ExecutorService javadoc you will find:
Memory Consistency Effects: Actions in the thread before the Runnable or Callable task is presented in the ExecutorService happens - before any actions taken by this task, which in turn will happen - before the result is received via Future.get ().
This is enough to answer this:
"Do I need to synchronize access to the executor before interacting / submitting tasks?"
No no. It's good to create and submit jobs to any (correctly implemented) ExecutorService without external synchronization. This is one of the main design goals.
ExecutorService is a parallel utility, that is, it is designed to work to the maximum extent, without requiring synchronization for performance. (Synchronization causes thread conflict, which can degrade multithreading performance - especially when scaling to a large number of threads.)
There is no guarantee that at what time in the future tasks will be completed or completed (some may even be executed immediately in the same thread that sent them), however, the worker thread was guaranteed to see all the effects that the feed stream performed right up to the time of submission. Therefore (the thread that is running), your task can also safely read any data created for its use without synchronization, thread-safe classes, or any other form of “secure publication”. The act of sending a task alone is sufficient to "securely publish" the input to the task. You just need to make sure that the input data will not be changed in any way during the execution of the task.
Similarly, when you return the result of a task back via Future.get() , the receiving stream will be guaranteed to see all the effects created by the worker’s stream (both in the returned result and in any side effect, the worker changes - maybe an error can be made) .
This contract also implies that more tasks are quite suitable for the tasks themselves.
"Does ExecutorService provide thread safety?"
Now this part of the question is much more general. For example, it was not possible to find any thread security contract operator about the shutdownAndAwaitTermination method - although I note that the code sample in Javadoc does not use synchronization. (Although, perhaps, there is a hidden assumption that the shutdown is initiated by the same thread that created the Executor, and not, for example, a work thread?)
BTW I would recommend the book "Java Concurrency In Practice" for a good grounder in the world of parallel programming.