ロック
日本語 | 鍵、施錠 |
英語 | lock |
ふりがな | ろっく |
フリガナ | ロック |
ある対象に「鍵」を掛けることで、他が使用できない状態にすること。
複数のスレッドやアプリケーションが同時にひとつの処理対象にアクセスする場合、一連の処理が完了するまで、他のスレッドやアプリケーションに邪魔されたくない場合にロックを掛ける。
そうすると、他のスレッドやアプリケーションはアクセス時に一時停止するかエラーとなるため、先に処理を開始した側が安全に処理を完了させることができる。
マルチスレッドにおいては、同時に複数のスレッドがひとつのインスタンスにアクセスする場合に、同期を取るための「手段」として、synchronizedブロックもしくはsynchronizedメソッドを用いてロックを掛ける。
インスタンスにロックを掛けることで、あるスレッドがそのインスタンスへの処理を完了するまでは、他のインスタンスが処理を行えないようにする。
また、アプリケーション単位でもロックを行うことがある。
アプリケーションサーバーのように「複数のアプリケーションが起動されてはいけない」場合、「ロック用のファイル」を用意し、起動時にロックが掛かっているか確認し、掛かっていなければファイルにロックを掛け、掛かっていれば何もせずに終了する。
このように、ロックを掛ける対象が、必ずしも「処理の対象」とは限らない点に注意。
そのため、ロックは、同期や排他の「手段のひとつ」であり、フラグを使用する場合より強制力があるもの、と考えるのがいいだろう。
複数のスレッドやアプリケーションが同時にひとつの処理対象にアクセスする場合、一連の処理が完了するまで、他のスレッドやアプリケーションに邪魔されたくない場合にロックを掛ける。
そうすると、他のスレッドやアプリケーションはアクセス時に一時停止するかエラーとなるため、先に処理を開始した側が安全に処理を完了させることができる。
マルチスレッドにおいては、同時に複数のスレッドがひとつのインスタンスにアクセスする場合に、同期を取るための「手段」として、synchronizedブロックもしくはsynchronizedメソッドを用いてロックを掛ける。
インスタンスにロックを掛けることで、あるスレッドがそのインスタンスへの処理を完了するまでは、他のインスタンスが処理を行えないようにする。
また、アプリケーション単位でもロックを行うことがある。
アプリケーションサーバーのように「複数のアプリケーションが起動されてはいけない」場合、「ロック用のファイル」を用意し、起動時にロックが掛かっているか確認し、掛かっていなければファイルにロックを掛け、掛かっていれば何もせずに終了する。
このように、ロックを掛ける対象が、必ずしも「処理の対象」とは限らない点に注意。
そのため、ロックは、同期や排他の「手段のひとつ」であり、フラグを使用する場合より強制力があるもの、と考えるのがいいだろう。
参考サイト
// Sample.java
public class Sample
{
public static void main( String[] args )
{
try
{
// データクラス。
DataClass data = new DataClass();
// 別スレッドの方を呼び出します。
OtherThread thread = new OtherThread( data );
thread.start();
// 2秒待ちます。OtherThreadの方を先に
// 実行するためです。
Thread.sleep( 2 * 1000 );
// こちらでも。
System.out.println( "Sample開始" );
// synchronizedブロックを持つメソッドを呼び出します。
SynchronizeClass synchronizeClass = new SynchronizeClass();
synchronizeClass.methodHasSynchronizedBlock( "Sample", data );
System.out.println( "Sample終了" );
// OtherThread開始
// synchronizedブロック開始 from OtherThread
// Sample開始
// synchronizedブロック終了 from OtherThread
// synchronizedブロック開始 from Sample
// OtherThread終了
// synchronizedブロック終了 from Sample
// Sample終了
}
catch( InterruptedException e )
{
// sleep()メソッドが途中で中断されると
// InterruptedException例外が投げられます。
// 滅多にないですが。
e.printStackTrace();
}
}
}
/**
* 別スレッドとして実行するためのクラス。
*/
class OtherThread extends Thread
{
/** データクラス。 */
private DataClass data;
/** コンストラクタ。 */
public OtherThread( DataClass data )
{
this.data = data;
}
/**
* Threadクラスのrun()メソッドを
* オーバーライドしたメソッド。このメソッドが
* 別スレッドとして呼び出されます。
*/
public void run()
{
System.out.println( "OtherThread開始" );
// synchronizedブロックを持つメソッドを呼び出します。
SynchronizeClass synchronizeClass = new SynchronizeClass();
synchronizeClass.methodHasSynchronizedBlock( "OtherThread", data );
System.out.println( "OtherThread終了" );
}
}
/**
* 同期処理テスト用クラス。
*/
class SynchronizeClass
{
/**
* synchronizedブロックを持つメソッド
*/
public void methodHasSynchronizedBlock( String name, DataClass data )
{
try
{
// 変数dataが参照するインスタンスに対してロックを掛けます。
// 他のスレッドがロック中にここの処理をしようとした場合、
// ロックが解除されるまで停止し続けます。
synchronized( data )
{
// 変数dataが参照するインスタンスに対してロックを掛かりました。
System.out.println( "synchronizedブロック開始 from " + name );
// 5秒待ちます。
Thread.sleep( 5 * 1000 );
System.out.println( "synchronizedブロック終了 from " + name );
}
// ロックが解除しました。
// 解除待ちしていたスレッドは処理が再開されます。
}
catch( InterruptedException e )
{
// sleep()メソッドが途中で中断されると
// InterruptedException例外が投げられます。
// 滅多にないですが。
e.printStackTrace();
}
}
}
/**
* データクラス。
*/
class DataClass
{
}
public class Sample
{
public static void main( String[] args )
{
try
{
// データクラス。
DataClass data = new DataClass();
// 別スレッドの方を呼び出します。
OtherThread thread = new OtherThread( data );
thread.start();
// 2秒待ちます。OtherThreadの方を先に
// 実行するためです。
Thread.sleep( 2 * 1000 );
// こちらでも。
System.out.println( "Sample開始" );
// synchronizedブロックを持つメソッドを呼び出します。
SynchronizeClass synchronizeClass = new SynchronizeClass();
synchronizeClass.methodHasSynchronizedBlock( "Sample", data );
System.out.println( "Sample終了" );
// OtherThread開始
// synchronizedブロック開始 from OtherThread
// Sample開始
// synchronizedブロック終了 from OtherThread
// synchronizedブロック開始 from Sample
// OtherThread終了
// synchronizedブロック終了 from Sample
// Sample終了
}
catch( InterruptedException e )
{
// sleep()メソッドが途中で中断されると
// InterruptedException例外が投げられます。
// 滅多にないですが。
e.printStackTrace();
}
}
}
/**
* 別スレッドとして実行するためのクラス。
*/
class OtherThread extends Thread
{
/** データクラス。 */
private DataClass data;
/** コンストラクタ。 */
public OtherThread( DataClass data )
{
this.data = data;
}
/**
* Threadクラスのrun()メソッドを
* オーバーライドしたメソッド。このメソッドが
* 別スレッドとして呼び出されます。
*/
public void run()
{
System.out.println( "OtherThread開始" );
// synchronizedブロックを持つメソッドを呼び出します。
SynchronizeClass synchronizeClass = new SynchronizeClass();
synchronizeClass.methodHasSynchronizedBlock( "OtherThread", data );
System.out.println( "OtherThread終了" );
}
}
/**
* 同期処理テスト用クラス。
*/
class SynchronizeClass
{
/**
* synchronizedブロックを持つメソッド
*/
public void methodHasSynchronizedBlock( String name, DataClass data )
{
try
{
// 変数dataが参照するインスタンスに対してロックを掛けます。
// 他のスレッドがロック中にここの処理をしようとした場合、
// ロックが解除されるまで停止し続けます。
synchronized( data )
{
// 変数dataが参照するインスタンスに対してロックを掛かりました。
System.out.println( "synchronizedブロック開始 from " + name );
// 5秒待ちます。
Thread.sleep( 5 * 1000 );
System.out.println( "synchronizedブロック終了 from " + name );
}
// ロックが解除しました。
// 解除待ちしていたスレッドは処理が再開されます。
}
catch( InterruptedException e )
{
// sleep()メソッドが途中で中断されると
// InterruptedException例外が投げられます。
// 滅多にないですが。
e.printStackTrace();
}
}
}
/**
* データクラス。
*/
class DataClass
{
}
// Sample.java public class Sample { public static void main( String[] args ) { try { // データクラス。 DataClass data = new DataClass(); // 別スレッドの方を呼び出します。 OtherThread thread = new OtherThread( data ); thread.start(); // 2秒待ちます。OtherThreadの方を先に // 実行するためです。 Thread.sleep( 2 * 1000 ); // こちらでも。 System.out.println( "Sample開始" ); // synchronizedブロックを持つメソッドを呼び出します。 SynchronizeClass synchronizeClass = new SynchronizeClass(); synchronizeClass.methodHasSynchronizedBlock( "Sample", data ); System.out.println( "Sample終了" ); // OtherThread開始 // synchronizedブロック開始 from OtherThread // Sample開始 // synchronizedブロック終了 from OtherThread // synchronizedブロック開始 from Sample // OtherThread終了 // synchronizedブロック終了 from Sample // Sample終了 } catch( InterruptedException e ) { // sleep()メソッドが途中で中断されると // InterruptedException例外が投げられます。 // 滅多にないですが。 e.printStackTrace(); } } } /** * 別スレッドとして実行するためのクラス。 */ class OtherThread extends Thread { /** データクラス。 */ private DataClass data; /** コンストラクタ。 */ public OtherThread( DataClass data ) { this.data = data; } /** * Threadクラスのrun()メソッドを * オーバーライドしたメソッド。このメソッドが * 別スレッドとして呼び出されます。 */ public void run() { System.out.println( "OtherThread開始" ); // synchronizedブロックを持つメソッドを呼び出します。 SynchronizeClass synchronizeClass = new SynchronizeClass(); synchronizeClass.methodHasSynchronizedBlock( "OtherThread", data ); System.out.println( "OtherThread終了" ); } } /** * 同期処理テスト用クラス。 */ class SynchronizeClass { /** * synchronizedブロックを持つメソッド */ public void methodHasSynchronizedBlock( String name, DataClass data ) { try { // 変数dataが参照するインスタンスに対してロックを掛けます。 // 他のスレッドがロック中にここの処理をしようとした場合、 // ロックが解除されるまで停止し続けます。 synchronized( data ) { // 変数dataが参照するインスタンスに対してロックを掛かりました。 System.out.println( "synchronizedブロック開始 from " + name ); // 5秒待ちます。 Thread.sleep( 5 * 1000 ); System.out.println( "synchronizedブロック終了 from " + name ); } // ロックが解除しました。 // 解除待ちしていたスレッドは処理が再開されます。 } catch( InterruptedException e ) { // sleep()メソッドが途中で中断されると // InterruptedException例外が投げられます。 // 滅多にないですが。 e.printStackTrace(); } } } /** * データクラス。 */ class DataClass { }
「みだし」に含まれているページ
「解説」に含まれているページ
- break
- case
- close
- continue
- default
- do-while
- finally
- for
- forステートメント
- for初期化ステートメント
- staticブロック
- static初期化ブロック
- static初期化子
- switch
- switchステートメント
- synchronized
- synchronizedブロック
- synchronizedメソッド
- whileステートメント
- {
- インデント
- スコープ
- ステートメント
- タブ
- タブ文字
- デッドロック
- トランザクション
- ネスト
- バイト入力ストリーム
- バイト出力ストリーム
- ブロック
- ブロックします
- ブロック修飾子
- マルチスレッド
- モジュール
- ラベルステートメント
- ロック
- ローカルクラス
- ローカル変数
- ローカル変数宣言
- ローカル変数宣言ステートメント
- 修飾子
- 入れ子
- 再帰呼び出し
- 同期
- 変数
- 変数宣言
- 抜ける
- 文字入力ストリーム
- 文字出力ストリーム
- 空ステートメント
- 評価
「サンプルプログラムとか」に含まれているページ
- :
- break
- case
- catch
- continue
- default
- do-while
- doステートメント
- else
- for
- forステートメント
- for初期化ステートメント
- if
- return
- staticブロック
- static初期化ブロック
- switch
- switchステートメント
- synchronizedブロック
- whileステートメント
- {
- インスタンス初期化ブロック
- スコープ
- デッドロック
- ネスト
- ブロック
- ブロックします
- ブロック修飾子
- ラベル
- ラベルステートメント
- ロック
- ローカルクラス
- ローカル変数
- ローカル変数宣言
- ローカル変数宣言ステートメント
- 入れ子
- 寿命
- 空ステートメント