异步操作设计问题

我们项目有这样的代码,个人感觉不是很友好.
比如一个service类,里面有个操作可能需要异步化,那么我们自己的项目大概是这样的,为代码如下:

public class XXXServiceImpl implements XXXService{
    @Resource
    private XXXDao xxxDao;
    private LinkedBlockingDeque<X> dataQueue;

    @PostConstruct
    private synchronized void init() {
        if(dataQueue == null) {
            dataQueue = new LinkedBlockingDeque<X>();
            Thread updateThread = new Thread(new Runnable() {
                
                @Override
                public void run() {
                    while(true){
                        List<X> l = new ArrayList();
                        X xxx =  dataQueue.take();
                        l.add(xxx);
                        if(l.size == 200){
                          xxxDao.batchInsert(l);
                          l.clear();
                        }
                        //do something
                    }
             };
             updateThread.setDaemon(true);
             updateThread.setName("xxxx");
             updateThread.start();
         }
    }
    
    public void saveData(X xxx){
        dataQueue.add(xxx);
    }
}

然后每个这样的service都这样处理异步的.

===================================================================

个人觉得应该集中处理这种需要异步处理的情况,比如一个线程池,每个任务绑定一个callback处理方法,从线程池里面取出需要处理的异步任务,然后调用callback进行处理.
这样当重启应用的时候,还可以添加一个hook,shutdown这个线程池,等待所有任务都处理完后,才退出进程.

不知道大家的公司怎么处理的,是否也是有我们这样的代码呢?

阅读 4.9k
8 个回答
新手上路,请多包涵

使用消息队列。

jdk6 提供了,FutureTask 多线程异步处理。
jdk7 提供了,Fork/Join 都应该能满足你的要求。

我们目前没有这样的需求,有些公司是利用了缓存和数据库,应用程序写缓存,有后台程序从缓存同步到数据库

大众点评的zebra-dao 就是一个异步的dao实现,方法和你说的类似。

我们目前没有这样的需求,有些公司是利用了缓存和数据库,应用程序写缓存,有后台程序从缓存同步到数据库

大众点评的zebra-dao 就是一个异步的dao实现,方法和你说的类似。

直接用Spring的@Async

如果是后台的话,还是用消息队列对其进行解耦吧
使用线程或线程池不是说不可以,但是debug麻烦,逻辑也容易出错。

这样做应该会导致异步阻塞吧

关于线程池:

ExecutorService pool = Executors.newSingleThreadExecutor(); //单线程服务
ExecutorService pool = Executors.newFixedThreadPool(10);  //10个线程的线程池

关于callback : 可以参考 CallableFuture,通过它们可以在任务执行完毕之后得到任务执行结果.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题