假设我有一个带有单个成员消息(字符串)的类Base 。另一个类BaseHandler扩展了这个Base类。在这个处理程序中,我有一个print方法,它为基数设置一个值并打印它。在打印调用结束时,我将消息设置为空。当我创建 50000 个线程并运行处理程序的打印方法时,我偶尔会收到空指针异常。
问题:
为什么在显式赋值时会抛出空指针异常?
在这种情况下,每个线程将如何实例化 Base?
解决方案会将 Base.message 标记为 volatile 并删除空分配吗?(换句话说,如何在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();
}
}
}