I think that you deserve some clarification on the comments and also some clarification on what causes a race condition.
On race conditions-- the basic idea of all threading is that at anytime of execution the current thread that you are on could be rescheduled to a later time or another thread might be executing and accessing the same data in parrallel.
For one, the process IDs should be final as mentioned before. YOUR CODE WILL NOT BE THREAD SAFE UNTIL YOU DO THIS. Even though the ConcurrentSkipListSet<> is thread safe this doesn't stop the variable processIds from being reassigned by another thread. Also, Java is weird and to your processIds field must be marked final to guarantee that is initialized before the constructor completes. I found this stackoverflow post that explains some of the issues with object construction in java for some more reading. Constructor synchronization in Java. Basically, don't mark your constructor fields as synchronized, but if you want to guarantee variable initialization in the constructor, which in this case you do, then mark your field as final.
To answer your question on whether this is thread safe, the only answer would be that it depends on the client usage you are expecting. The methods you provided are indeed thread safe for their intended purposes as written, but a client could use them and produce a race condition. Your intuition on whether or not it would be 100% necessary to use the synchronized keyword is correct. Yet, what the comments are alluding too is that not making these methods explicitly thread safe might have some dire consequence in the future for the maintainability and correctness of your code.
A client could still use the API you provide in an unsafe way that could result in a race condition as mentioned in one of the comments. If you are providing an interface to a client you may not care about this... or you might care about this and want to provide a mechanism for the client to make multiple accesses to your class with guaranteed thread safety.
Overall, I would probably recommend that you mark your methods as synchronized for a couple of reasons 1) it makes in clear to the client that they are accessing methods that are thread safe which is very important. I can easily imagine a situation where the client decides to use a lock when it isn't needed at the detriment of performance. 2) Someone could change your methods to contain some different logic in the future that requires the synchronized keyword (this isn't so unlikely because you seem to already be in a threaded environment).