使用多线程时@Service工具类出现NullPoint错误解决

今天使用线程池来进行数据库操作是出现了空指针的错误,debug过程中发现Service类并没有因为@Autowired注解而自动注入
原因分析大概是:线程池新开的线程中不能使用 @Autowired 注入对象从而导致 NullPointerException被抛出
  • 所以我们应该从 Spring 容器中直接获取该Service对象进行使用。

首先来看看原先的代码:
线程池:

public static final ThreadPoolExecutor poolExecutor = 
                  new ThreadPoolExecutor(3, 6, 2, 
                  TimeUnit.SECONDS,new ArrayBlockingQueue<Runnable>(3));

进行数据库操作的线程:

@Component
@Scope("prototype")//spring 多例
public class DBThread implements Runnable {
    private Integer id;
    private static ReentrantLock lock = new ReentrantLock(true);

    @Autowired
    GoodsService goodsService;

    public DBThread(){
        super();
    }
    public DBThread(int id) {
        this.id = id;
    }
    
    @Override
    public void run() {
        //在数据库插入数据
        lock.lock();
        try{
            System.out.println("当前线程为"+Thread.currentThread().getId());
            goodsService.buy(id);
        }catch (Exception e){
            throw e;
        }finally {
            System.out.println("当前线程解锁"+Thread.currentThread().getId());
            lock.unlock();
        }
    }
}

执行类:

@RequestMapping("/buy/{Id}")
    public String buy(@PathVariable("Id")Integer id){
        ThreadPoolManager.poolExecutor.execute(new DBThread(id));
        return "redirect:/refreshgoods";
    }
然后我们修改的思路便是将DBThread 类中的goodsService从自动注入变为我们主动的从Applicationcaontext中将其取出来使用

也就是修改为如下代码:

private static ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml");

    private static GoodsService goodsService;
    static {
        goodsService = context.getBean(GoodsService.class);
    }

完整的:

@Component
@Scope("prototype")//spring 多例
public class DBThread implements Runnable {
    private Integer id;
    private static ReentrantLock lock = new ReentrantLock(true);
    private static ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml");

    private static GoodsService goodsService;
    static {
        goodsService = context.getBean(GoodsService.class);
    }

    public DBThread(){
        super();
    }
    public DBThread(int id) {
        this.id = id;
    }

    @Override
    public void run() {
        //在数据库插入数据
        lock.lock();
        try{
            System.out.println("当前线程为"+Thread.currentThread().getId());
            goodsService.buy(id);
        }catch (Exception e){
            throw e;
        }finally {
            System.out.println("当前线程解锁"+Thread.currentThread().getId());
            lock.unlock();
        }
    }
}
这样就没有再出现空指针的错误了
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值