多线程下巧妙避免空指针

案例

public class A {
    
    

	private B b;

	public void setB(B b) {
    
    
		this.b = b;
	}

	public void doSomeThings() {
    
    
		if(b != null) {
    
    
		//此处即使做了非空判断,多线程时也不能保证在执行b的方法时b不空
			b.doSomeThings();
		}
	}
}

A a = new A();
B b = new B();
a.setB(b);

new Thread() {
    
    
	void run() {
    
    
		a.setB(null);
    }
}.start();

new Thread() {
    
    
	void run() {
    
    
		a.doSomeThings();
    }
}.start();

代码如上,多线程访问A的对象a,为了确保线程安全,常用的方法是加锁。比如下面这样:

	public synchronized void setB(B b) {
    
    
		this.b = b;
	}

	public synchronized void doSomeThings() {
    
    
		if(b != null) {
    
    
			b.doSomeThings();
		}
	}

新方法

现在介绍一种新方法

public void doSomeThings() {
    
    
	B tmpB = b;
	if(tmpB != null) {
    
    
		tmpB.doSomeThings();
	}

将b赋值给一个局部变量tmpB,在执行B方法前判断tmpB是否为空。
上述方法中,将b赋值给一个局部变量tmpB时如果b不空,那么在执行tmpB.doSomeThings()时即使b被置空了,tmpB也不会为空。而且tmpB是一个局部变量,当A.doSomeThings()方法执行完后就释放了,所以不会造成内存泄漏。

但是该方法要求A.doSomeThings()不能在短时间内被频繁调用,否则会产生大量的局部变量,这些局部变量又会被一下子回收,造成内存抖动。

猜你喜欢

转载自blog.csdn.net/jiejingguo/article/details/129687947