TL;DR
関数やデータ構造が、複数のスレッドから同時に呼び出されたりアクセスされたりしても、競合状態やデータの破壊を起こさずに正しく動作する性質。
なぜ必要か
Wikipedia によると、スレッドセーフでないデータ構造は、異なるスレッドから同時にアクセスしてはいけない。ライブラリがスレッドセーフかどうかを知らなければ、それを使うプログラムがスレッドセーフかどうかも判断できない。
仕組み
Wikipedia では、スレッドセーフを実現する方法を 2 つに分けている。
1 つ目は、状態を共有しない方法である。各スレッドが変数の複製を持つスレッドローカルストレージや、作った後で状態を変えられないイミュータブルなオブジェクトがある。
2 つ目は、共有する状態へのアクセスを同期する方法である。一度に 1 つのスレッドだけが読み書きできるようにする相互排他(クリティカルセクション)や、他のスレッドに割り込まれないアトミック操作がある。
注意点
スレッドコンパチブルとは異なる。スレッドコンパチブルなものは、呼び出し側が同期すればマルチスレッドの環境で正しく動作するが、同期しなければ正しく動作しない。