我们项目有这样的代码,个人感觉不是很友好.
比如一个service
类,里面有个操作可能需要异步化,那么我们自己的项目大概是这样的,为代码如下:
public class XXXServiceImpl implements XXXService{ @Resource private XXXDao xxxDao; private LinkedBlockingDequedataQueue; @PostConstruct private synchronized void init() { if(dataQueue == null) { dataQueue = new LinkedBlockingDeque (); Thread updateThread = new Thread(new Runnable() { @Override public void run() { while(true){ List 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
这个线程池,等待所有任务都处理完后,才退出进程.
不知道大家的公司怎么处理的,是否也是有我们这样的代码呢?
关于线程池:
ExecutorService pool = Executors.newSingleThreadExecutor(); //单线程服务
ExecutorService pool = Executors.newFixedThreadPool(10); //10个线程的线程池
关于callback
: 可以参考 Callable
和Future
,通过它们可以在任务执行完毕之后得到任务执行结果.
这样做应该会导致异步阻塞吧
如果是后台的话,还是用消息队列对其进行解耦吧
使用线程或线程池不是说不可以,但是debug麻烦,逻辑也容易出错。
直接用Spring的@Async
我们目前没有这样的需求,有些公司是利用了缓存和数据库,应用程序写缓存,有后台程序从缓存同步到数据库
大众点评的zebra-dao 就是一个异步的dao实现,方法和你说的类似。
我们目前没有这样的需求,有些公司是利用了缓存和数据库,应用程序写缓存,有后台程序从缓存同步到数据库
大众点评的zebra-dao 就是一个异步的dao实现,方法和你说的类似。
jdk6 提供了,FutureTask 多线程异步处理。
jdk7 提供了,Fork/Join 都应该能满足你的要求。
使用消息队列。