在多线程修改对象a的时候,即使加了空判断也容易发生空指针。
因为在判断a不为空后,另一个线程刚好把a置空,这时去使用a时就触发空指针异常了。
if (a != null) {
a.foo();
}
多线程并发模拟:一个线程间隔10ms不停地读字符串str的长度,另一个线程每5ms把str置空或者重新赋值。
public class Test{
static String str = "str";
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
while(true) {
if (str != null) {
System.out.println(str.length());
}
sleep(10);
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
while(true) {
if (str == null) {
str = "newStr";
} else {
str = null;
}
sleep(5);
}
}
}).start();
}
private static void sleep(long time) {
try {
Thread.sleep(time);
} catch (Exception e) {
// ignore
}
}
}
运行很快就会
Exception in thread "Thread-0" java.lang.NullPointerException
at app.Test$1.run(Test.java:16)
at java.lang.Thread.run(Thread.java:748)
如果不用try-catch,可以使用一个局部变量temp引用str,判断和使用temp不会空指针
public class Test{
static String str = "str";
public static void main(String[] args) {
new Thread(new Runnable(){
@Override
public void run() {
while(true) {
// if (str != null) {
// System.out.println(str.length());
// }
String temp = str;
if (temp != null) {
System.out.println(temp.length());
}
sleep(10);
}
}
}).start();
new Thread(new Runnable(){
@Override
public void run() {
while(true) {
if (str == null) {
str = "newStr";
} else {
str = null;
}
sleep(5);
}
}
}).start();
}
private static void sleep(long time) {
try {
Thread.sleep(time);
} catch (Exception e) {
// ignore
}
}
}
网友评论