Javaのオブジェクトレベルロックとクラスレベルロックの違いを徹底解説
はじめに:マルチスレッド環境とロックの必要性
マルチスレッド環境では、2つ以上のスレッドが同時に共有リソースへアクセスする可能性があり、データの不整合や予期しない動作を引き起こす恐れがあります。Javaではこの問題を防ぐために「ロック(Lock)」という仕組みを提供しており、共有リソースやオブジェクトへの同時アクセスを制御できます。
Javaのロックは、適用対象によって大きく次の2つのレベルに分類されます。
- オブジェクトレベルロック … 非staticメソッドや非staticのコードブロックに対して、同時に1つのスレッドからしかアクセスできないようにしたい場合に使用します。
- クラスレベルロック … 実行時に存在するすべてのインスタンスを通じて、複数のスレッドが同期ブロックへ同時に入るのを防ぎたい場合に使用します。staticデータをスレッドセーフにする際に必ず使用すべきロックです。
オブジェクトレベルロックとクラスレベルロックの比較表
| No. | 比較項目 | オブジェクトレベルロック | クラスレベルロック |
|---|---|---|---|
| 1 | 基本 | 非staticメソッドや非staticのコードブロックに、同時に1つのスレッドしかアクセスできないようにしたい場合に使用します。 | 実行時に存在するすべてのインスタンスにおいて、複数のスレッドが同期ブロックへ同時に入るのを防ぎたい場合に使用します。 |
| 2 | static / 非static | 非staticデータ(インスタンス変数など)をスレッドセーフにするために使用します。 | staticデータ(クラス変数など)をスレッドセーフにするために使用します。 |
| 3 | ロックの数 | クラスの各インスタンス(オブジェクト)がそれぞれ独自のロックを持ちます。 | クラスのインスタンスは複数存在し得ますが、そのクラスに対応するClassオブジェクトのロックはJVM内に常に1つだけです。 |
クラスレベルロックの実装例
クラスレベルロックを取得するには、synchronizedブロックのモニターとしてクラス名.class(Classオブジェクト)を指定します。
public class ClassLevelLockExample {
public void classLevelLockMethod() {
synchronized (ClassLevelLockExample.class) {
// ここに排他制御が必要な処理を記述
}
}
}また、static synchronizedメソッドを定義した場合も、暗黙的にこのクラスレベルロックが使用されます。
オブジェクトレベルロックの実装例
オブジェクトレベルロックを取得するには、synchronizedブロックのモニターとしてthis(現在のインスタンス自身)を指定します。
public class ObjectLevelLockExample {
public void objectLevelLockMethod() {
synchronized (this) {
// ここに排他制御が必要な処理を記述
}
}
}インスタンスメソッドにsynchronized修飾子を付けた場合も、暗黙的にthisのロックが取得されます。
まとめ
オブジェクトレベルロックはインスタンス単位の排他制御、クラスレベルロックはクラス全体(全インスタンス共通)の排他制御を行うための仕組みです。インスタンス固有の状態を守るなら前者を、staticフィールドなどクラス全体で共有される状態を守るなら後者を選択することで、マルチスレッド環境でも安全なプログラムを実現できます。
-
JavaにおけるThreadとRunnableの違いを徹底解説!使い分けのポイント
Javaで新しいスレッドを作成する方法は主に2つあります。1つ目はThreadクラスを継承(extends)する方法、2つ目はRunnableインターフェースを実装(implements)する方法です。それぞれの特徴と違いを理解することで、状況に応じた適切な選択ができるようになります。 スレッド作成の2つの方法 1. Threadクラスを継承する方法 Threadクラスのサブクラスとして新しいクラスを宣言し、そのサブクラス内でrun()メソッドをオーバーライドします。その後、サブクラスのインスタンスを生成し、start()メソッドを呼び出すことでスレッドが実行されます。 2. Runna
-
Javaのオブジェクトレベルロックとクラスレベルロックの違いを徹底解説
マルチスレッドアプリケーションにおいて、オブジェクトレベルロックとクラスレベルロックは、どちらも同期(synchronization)を実現するための重要な仕組みです。この記事では、それぞれの特徴や動作の違いを、コード例と実行結果とともにわかりやすく解説します。 オブジェクトレベルロックとは Javaでは、すべてのオブジェクトが固有のロックを1つ持っています。あるスレッドが特定のオブジェクトに対してsynchronizedメソッドを実行したい場合、まずそのオブジェクトのロックを取得する必要があります。 ロックを取得できたスレッドは、そのオブジェクトの任意のsynchronizedメソッドを実行