単一のメンバーメッセージ(文字列)を持つクラスBaseがあるとします。このBaseクラスを拡張する別のクラスBaseHandler。このハンドラーには、値をベースに設定して出力するprintメソッドがあります。print の呼び出しの最後に、メッセージを null に設定しています。50000 スレッドを作成してハンドラーの print メソッドを実行すると、ときどき null ポインター例外が発生します。
質問:
値を明示的に代入しているときに null ポインター例外がスローされるのはなぜですか?
この場合、各スレッドはどのようにベースをインスタンス化しますか?
ソリューションは Base.message を揮発性としてマークし、null 割り当てを削除しますか? (つまり、Base.messageでスレッドセーフを達成する方法
以下のコードを見てください。
public class Base {
public String message;
}
public class BaseHandler extends Base{
protected static final Object lock = new Object();
public void printMessage( ){
synchronized ( lock ) { //This block is thread safe
System.out.println( message.toUpperCase( ) );
message = null;
}
}
}
public class Test {
public static void main(String[] args){
final BaseHandler handler = new BaseHandler();
for (int i = 0; i < 50000; i++) {
Runnable task = new Runnable(){
@Override
public void run( ) {
handler.message = "Hello world! ";
handler.printMessage( );
}
};
Thread worker = new Thread(task);
worker.setName(String.valueOf(i));
worker.start();
}
}
}