首页 新闻 赞助 找找看

java并发问题

0
悬赏园豆:50 [已解决问题] 解决于 2018-09-10 14:03

package async.up;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;

public class DelayRetryUtil {

private static DelayQueue<RetryItem> RETRY_DELAY_QUEUE = null;

static boolean offer(RetryItem e) {

    // 延迟初始化,因为延迟队列是耗费cpu及内存资源的开销,在真正使用时才进行初始化,并执行任务
    // todo 后续可以增加通过其他线程动态监测RETRY_DELAY_QUEUE不再使用时,进行销毁
    if(RETRY_DELAY_QUEUE == null) {
        synchronized (DelayRetryUtil.class) {
            if(RETRY_DELAY_QUEUE == null) {
                initConsumer();
            }
        }
    }
    return RETRY_DELAY_QUEUE.offer(e);
}

private static void initConsumer() {
    RETRY_DELAY_QUEUE  = new DelayQueue<>();
    new Thread(() -> {
        boolean go = true;
        while(go) {
            try {
                RetryItem i = RETRY_DELAY_QUEUE.take();

                if(i != null) {
                    System.out.println("123");
                }
            } catch (InterruptedException e1) {
                go = false;
            }
        }
    }).start();
}


static class RetryItem implements Delayed{

    private long startTime;

    RetryItem(long startTime) {
        this.startTime = startTime;
    }

    @Override
    public long getDelay(TimeUnit unit) {

        return unit.convert(startTime - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
    }

    @Override
    public int compareTo(Delayed o) {
        RetryItem c = (RetryItem) o;
        return this.startTime - c.startTime > 0 ? 1 : (this.startTime - c.startTime < 0 ? -1 : 0);
    }
}

}

上面的程序中,在高并发环境下,return RETRY_DELAY_QUEUE.offer(e); 会不会有NullPointException,以及为什么了?

wudiffs的主页 wudiffs | 初学一级 | 园豆:157
提问于:2018-09-07 09:13
< >
分享
最佳答案
0

会不会NullPointException 我不太清楚,但是这种双检锁在单例模式下,需要在对象上加volatile,否则在给对象初始化的时候,可能因为重排序的问题,导致第一个if判断不满足,但是对象本身并不可用。 你可以网上查一查,双检锁的单例模式,必须要加volatile的。

收获园豆:50
让我发会呆 | 老鸟四级 |园豆:2909 | 2018-09-07 13:35

对,你的说法是对的,我们讨论发现了这个问题,但是本地验证的时候没复现,加上volatile就完美了。

wudiffs | 园豆:157 (初学一级) | 2018-09-10 14:02
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册