ブロックします
日本語 | 止める、妨げる、壁になる |
英語 | block |
ふりがな | ぶろっくします |
フリガナ | ブロックシマス |
処理が完了するまでメソッドが返ってこないこと。
ある意味当然のことだが、メソッドは、処理が完了しなければ返ってこない。
これを、「処理が完了するまでメソッドはブロックします」と表現する。
特に、これはストリームのような、処理の完了までどれだけ時間が掛かるか分からない、外部へのアクセスを行うメソッドに対して使用する。
たとえばネットワークへアクセスして他のマシンからデータを取得する場合、取得するメソッドはデータが取得できるまでreturnで返らない。つまり、メソッドがデータを取得できるまで処理を止める、つまり「ブロックする」ということである。
このような処理の場合、いつ処理が完了するか分からないため、メソッドからいつ返ってくるか分からず、その間プログラムが停止することになる。ユーザーは「なぜ止まっているのか」が分からず、アプリケーションがフリーズした、と思うことになり、強制終了させるだろう。
そのため、長時間ブロックされる可能性があるメソッドは、使用をやめるか、別スレッドから実行してユーザーインターフェイスはそのまま使用できるようにすることが望ましい。
「使用をやめる」場合、ブロックを行わないメソッドを使用することになる。
たとえばネットワークへアクセスする場合、ネットワークへ非同期にアクセスするクラスを使用することで、「メソッドを呼び出したらデータを取得するまで返らない」ではなく、「データが取得できたら指定したメソッドを呼び出してデータを渡してもらう」という処理にすることができる。
こういった、ブロックを行わない(非ブロック)ようにすることで、ユーザーに「処理を待たせる」必要がなくなる。
ただし、非ブロック処理を行う場合でも、マルチスレッドを使用する場合にでも、同期を取る必要があり、プログラムが複雑になるため注意すること。
名詞としての「ブロック」は別物なので注意。
詳しくは「ブロック」の項目を参照。
ある意味当然のことだが、メソッドは、処理が完了しなければ返ってこない。
これを、「処理が完了するまでメソッドはブロックします」と表現する。
特に、これはストリームのような、処理の完了までどれだけ時間が掛かるか分からない、外部へのアクセスを行うメソッドに対して使用する。
たとえばネットワークへアクセスして他のマシンからデータを取得する場合、取得するメソッドはデータが取得できるまでreturnで返らない。つまり、メソッドがデータを取得できるまで処理を止める、つまり「ブロックする」ということである。
このような処理の場合、いつ処理が完了するか分からないため、メソッドからいつ返ってくるか分からず、その間プログラムが停止することになる。ユーザーは「なぜ止まっているのか」が分からず、アプリケーションがフリーズした、と思うことになり、強制終了させるだろう。
そのため、長時間ブロックされる可能性があるメソッドは、使用をやめるか、別スレッドから実行してユーザーインターフェイスはそのまま使用できるようにすることが望ましい。
「使用をやめる」場合、ブロックを行わないメソッドを使用することになる。
たとえばネットワークへアクセスする場合、ネットワークへ非同期にアクセスするクラスを使用することで、「メソッドを呼び出したらデータを取得するまで返らない」ではなく、「データが取得できたら指定したメソッドを呼び出してデータを渡してもらう」という処理にすることができる。
こういった、ブロックを行わない(非ブロック)ようにすることで、ユーザーに「処理を待たせる」必要がなくなる。
ただし、非ブロック処理を行う場合でも、マルチスレッドを使用する場合にでも、同期を取る必要があり、プログラムが複雑になるため注意すること。
名詞としての「ブロック」は別物なので注意。
詳しくは「ブロック」の項目を参照。
参考サイト
// Sample.java
import java.io.InputStream;
import java.io.IOException;
public class Sample
{
public static void main( String[] args )
{
NetworkInputStream networkInputStream = null;
try
{
// NetworkInputStreamクラスを作ります。
networkInputStream = new NetworkInputStream();
while( true )
{
// ネットワークから1バイト取得します(のつもり)。
int i = networkInputStream.read();
if( i == -1 )
{
// -1が返されてきたら終わりです。
break;
}
// 出力します。
System.out.println( "0x" + Integer.toHexString( i ) + " ( " + i + " )" );
}
// NetworkInputStream#read()
// ネットワークから読み込み中(のつもり)
// ネットワークから読み込み完了(のつもり)
// 0x1 ( 1 )
// NetworkInputStream#read()
// ネットワークから読み込み中(のつもり)
// ネットワークから読み込み完了(のつもり)
// 0x2 ( 2 )
// NetworkInputStream#read()
// ネットワークから読み込み中(のつもり)
// ネットワークから読み込み完了(のつもり)
// 0x3 ( 3 )
// NetworkInputStream#read()
// もう読み込めません。
// read()メソッドは、呼びだした後、データを取得するまで
// 返ってきません。これがつまり「read()メソッドはデータを
// 取得するまでブロックする」ということです。
// ネットワークから取得する場合等、データの取得にどれだけ
// 時間が掛かるか分からない場合、このように「ブロックする」
// 処理は、ユーザーインターフェイスを著しく悪くする可能性が
// あるため、別スレッドで呼び出す等の対策が必要です。
}
catch( IOException e )
{
// 読み込みに失敗した際に、read()メソッドが
// IOException例外を投げます。
e.printStackTrace();
}
finally
{
// 処理が終わったら、最後にclose()メソッドを呼んで
// 後処理をします。また、これは必ず行うため、
// finally内で行います。
try
{
if( networkInputStream != null )
{
networkInputStream.close();
}
}
catch( IOException e )
{
// close()メソッドはIOExceptionがthrows指定されているので
// 一応受け取ります。
e.printStackTrace();
}
}
}
}
/**
* NetworkInputStreamクラス。
* InputStreamクラスのサブクラスです。
*/
class NetworkInputStream extends InputStream
{
// カウンター。
private int counter = 1;
/**
* read()メソッド。
* InputStreamクラスのread()メソッドをオーバーライドしたものです。
* このクラスを利用するバイト入力ストリームクラスの
* read()メソッドから呼び出されます。
*/
public int read() throws IOException
{
try
{
System.out.println( "NetworkInputStream#read()" );
// カウンターの最大値を3にします。
if( counter > 3 )
{
// 3を超えたら「最後」の印として-1を返します。
System.out.println( "もう読み込めません。" );
return -1;
}
System.out.println( "ネットワークから読み込み中(のつもり)" );
// 3秒待ちます。
// sleep()メソッドの引数には「ミリ秒」を渡すので、
// 秒に1000を掛けておきます。
Thread.sleep( 5 * 1000 );
System.out.println( "ネットワークから読み込み完了(のつもり)" );
// カウンターの数を返します。
// 通常は、こればbyte型の配列だったり、ファイルだったり
// するわけです。
int i = counter;
++counter;
return i;
}
catch( InterruptedException e )
{
// sleep()メソッドが途中で中断されると
// InterruptedException例外が投げられます。
// 滅多にないですが。
e.printStackTrace();
return -1;
}
}
}
import java.io.InputStream;
import java.io.IOException;
public class Sample
{
public static void main( String[] args )
{
NetworkInputStream networkInputStream = null;
try
{
// NetworkInputStreamクラスを作ります。
networkInputStream = new NetworkInputStream();
while( true )
{
// ネットワークから1バイト取得します(のつもり)。
int i = networkInputStream.read();
if( i == -1 )
{
// -1が返されてきたら終わりです。
break;
}
// 出力します。
System.out.println( "0x" + Integer.toHexString( i ) + " ( " + i + " )" );
}
// NetworkInputStream#read()
// ネットワークから読み込み中(のつもり)
// ネットワークから読み込み完了(のつもり)
// 0x1 ( 1 )
// NetworkInputStream#read()
// ネットワークから読み込み中(のつもり)
// ネットワークから読み込み完了(のつもり)
// 0x2 ( 2 )
// NetworkInputStream#read()
// ネットワークから読み込み中(のつもり)
// ネットワークから読み込み完了(のつもり)
// 0x3 ( 3 )
// NetworkInputStream#read()
// もう読み込めません。
// read()メソッドは、呼びだした後、データを取得するまで
// 返ってきません。これがつまり「read()メソッドはデータを
// 取得するまでブロックする」ということです。
// ネットワークから取得する場合等、データの取得にどれだけ
// 時間が掛かるか分からない場合、このように「ブロックする」
// 処理は、ユーザーインターフェイスを著しく悪くする可能性が
// あるため、別スレッドで呼び出す等の対策が必要です。
}
catch( IOException e )
{
// 読み込みに失敗した際に、read()メソッドが
// IOException例外を投げます。
e.printStackTrace();
}
finally
{
// 処理が終わったら、最後にclose()メソッドを呼んで
// 後処理をします。また、これは必ず行うため、
// finally内で行います。
try
{
if( networkInputStream != null )
{
networkInputStream.close();
}
}
catch( IOException e )
{
// close()メソッドはIOExceptionがthrows指定されているので
// 一応受け取ります。
e.printStackTrace();
}
}
}
}
/**
* NetworkInputStreamクラス。
* InputStreamクラスのサブクラスです。
*/
class NetworkInputStream extends InputStream
{
// カウンター。
private int counter = 1;
/**
* read()メソッド。
* InputStreamクラスのread()メソッドをオーバーライドしたものです。
* このクラスを利用するバイト入力ストリームクラスの
* read()メソッドから呼び出されます。
*/
public int read() throws IOException
{
try
{
System.out.println( "NetworkInputStream#read()" );
// カウンターの最大値を3にします。
if( counter > 3 )
{
// 3を超えたら「最後」の印として-1を返します。
System.out.println( "もう読み込めません。" );
return -1;
}
System.out.println( "ネットワークから読み込み中(のつもり)" );
// 3秒待ちます。
// sleep()メソッドの引数には「ミリ秒」を渡すので、
// 秒に1000を掛けておきます。
Thread.sleep( 5 * 1000 );
System.out.println( "ネットワークから読み込み完了(のつもり)" );
// カウンターの数を返します。
// 通常は、こればbyte型の配列だったり、ファイルだったり
// するわけです。
int i = counter;
++counter;
return i;
}
catch( InterruptedException e )
{
// sleep()メソッドが途中で中断されると
// InterruptedException例外が投げられます。
// 滅多にないですが。
e.printStackTrace();
return -1;
}
}
}
// Sample.java import java.io.InputStream; import java.io.IOException; public class Sample { public static void main( String[] args ) { NetworkInputStream networkInputStream = null; try { // NetworkInputStreamクラスを作ります。 networkInputStream = new NetworkInputStream(); while( true ) { // ネットワークから1バイト取得します(のつもり)。 int i = networkInputStream.read(); if( i == -1 ) { // -1が返されてきたら終わりです。 break; } // 出力します。 System.out.println( "0x" + Integer.toHexString( i ) + " ( " + i + " )" ); } // NetworkInputStream#read() // ネットワークから読み込み中(のつもり) // ネットワークから読み込み完了(のつもり) // 0x1 ( 1 ) // NetworkInputStream#read() // ネットワークから読み込み中(のつもり) // ネットワークから読み込み完了(のつもり) // 0x2 ( 2 ) // NetworkInputStream#read() // ネットワークから読み込み中(のつもり) // ネットワークから読み込み完了(のつもり) // 0x3 ( 3 ) // NetworkInputStream#read() // もう読み込めません。 // read()メソッドは、呼びだした後、データを取得するまで // 返ってきません。これがつまり「read()メソッドはデータを // 取得するまでブロックする」ということです。 // ネットワークから取得する場合等、データの取得にどれだけ // 時間が掛かるか分からない場合、このように「ブロックする」 // 処理は、ユーザーインターフェイスを著しく悪くする可能性が // あるため、別スレッドで呼び出す等の対策が必要です。 } catch( IOException e ) { // 読み込みに失敗した際に、read()メソッドが // IOException例外を投げます。 e.printStackTrace(); } finally { // 処理が終わったら、最後にclose()メソッドを呼んで // 後処理をします。また、これは必ず行うため、 // finally内で行います。 try { if( networkInputStream != null ) { networkInputStream.close(); } } catch( IOException e ) { // close()メソッドはIOExceptionがthrows指定されているので // 一応受け取ります。 e.printStackTrace(); } } } } /** * NetworkInputStreamクラス。 * InputStreamクラスのサブクラスです。 */ class NetworkInputStream extends InputStream { // カウンター。 private int counter = 1; /** * read()メソッド。 * InputStreamクラスのread()メソッドをオーバーライドしたものです。 * このクラスを利用するバイト入力ストリームクラスの * read()メソッドから呼び出されます。 */ public int read() throws IOException { try { System.out.println( "NetworkInputStream#read()" ); // カウンターの最大値を3にします。 if( counter > 3 ) { // 3を超えたら「最後」の印として-1を返します。 System.out.println( "もう読み込めません。" ); return -1; } System.out.println( "ネットワークから読み込み中(のつもり)" ); // 3秒待ちます。 // sleep()メソッドの引数には「ミリ秒」を渡すので、 // 秒に1000を掛けておきます。 Thread.sleep( 5 * 1000 ); System.out.println( "ネットワークから読み込み完了(のつもり)" ); // カウンターの数を返します。 // 通常は、こればbyte型の配列だったり、ファイルだったり // するわけです。 int i = counter; ++counter; return i; } catch( InterruptedException e ) { // sleep()メソッドが途中で中断されると // InterruptedException例外が投げられます。 // 滅多にないですが。 e.printStackTrace(); return -1; } } }
「みだし」に含まれているページ
「サンプルプログラムとか」に含まれているページ
- (参照している単語はありません)