Javaは言語仕様レベルでマルチスレッド下での利用を想定した機能が提供されているという特徴があります。同じプロセス空間上で複数のスレッドが動作する、という状況で注意することは資源の排他制御です。あるスレッドが特定のオブジェクトの値を参照して動作している途中で、別のスレッドがそのオブジェクトの値を変更するとどうなるのか、といった、シングルスレッドでは考える必要のなかった問題について色々考慮が必要になります。
Javaでは同期ブロックを使ってスレッド間の排他制御を行う仕組みがあります。同期ブロックの指定方法は、
synchronized (object) { : }の様に、synchronizedを使います。このときロックの対象となるオブジェクト(上記の場合はobject)を指定します。同じオブジェクトをロックの対象とする同期ブロックは、同時に1つのスレッドしか実行できないので、これにより排他制御が行えます。
同期ブロックは入る時と出るときの(JavaVMでの)処理が色々あるので、あまり頻繁に使用するとパフォーマンスに影響が出る可能性がありますので、本当に必要最小限だけ使うように注意する必要があります。
メソッド全体を同期ブロックにする事もできて、
public synchronized void print() { :というように書きます。この場合ロックの対象となるオブジェクトは、このメソッドを持つオブジェクト(this)そのものです。
では(インスタンスを持たない)staticなメソッド(クラスメソッド)の場合はどうでしょうか。同様に、
public static synchronized void usage() { :の様にsynchronizedをつければstaticなメソッドも同期ブロックになります。この場合ロックの対象となるオブジェクトは、このメソッドが定義されているクラスオブジェクトになります。
staticなメソッドの内部で同期ブロックを定義するには、
synchronized (Hoge.class) { : }の様に、メソッドが定義されているクラスオブジェクトをロックの対象となるように、クラス名.classを指定します。