How do you implement thread safety in a highly concurrent application? Explain the internal workings of synchronized blocks and locks.