需求:
最近要实现一个自动派单功能,就是如果有任务来了,那么任务平均分配给现有的员工,如果之前取了任务的员工下次来任务时就分配给下一个,如果有新员工则将员工添加到队列的最后,如果有员工离职就将员工信息从队列里移除。
实现:
1.写一个定时任务,定时将任务放入任务队列中TaskQueue,并将员工放入User队列中,如果员工已存在则不添加,如果新员工则加入队列中,如果员工不存在了就从队列中移除。
2.写一个线程,从任务队列中取任务,如果任务不存在则阻塞,取到任务后,将该任务派给下一个员工,并将该员工添加到员工队列末尾,这样达到按员工次序分配任务。
3.实现一个任务队列,如果在取任务时任务不存在则阻塞。
4.实现一个员工队列,在取下一个员工后将该员工从列头移到列尾,并且可以将新员工加入到队列未尾,可以将不存在的员工从队列中移除。
核心代码:
import java.util.Collection; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; /** * 任务队列 * 如果在取任务时没有任务,则阻塞 * @author dg * */ public class TaskQueue { private static TaskQueue instance; private static BlockingQueue queue = null; private TaskQueue(){ queue = new LinkedBlockingDeque(); } public static TaskQueue getInstance(){ if(instance == null){ instance = new TaskQueue(); } return instance; } /** * 获取队列大小 * @return */ public static int getSize(){ return queue.size(); } /** * 放入队列中 * @param msg */ public void put(Object obj){ if(obj != null){ try { queue.put(obj); } catch (InterruptedException e) { e.printStackTrace(); } } } /** * 放入队列中 * @param msg */ public void putAll(Collection objs){ if(objs != null){ queue.addAll(objs); } } /** * 从队列中取出一个 * @return */ public Object take(){ try { Object obj = queue.take(); return obj; } catch (InterruptedException e) { e.printStackTrace(); } return null; } }
/** * 存放即将被派任务的员工 * 每次取出员工时不移除该员工,而是将其放到队列末尾 * 如果员工已不存在,将其移除 * @author dg * */ public class UserQueue { private static UserQueue instance = null; private static BlockingQueue<User> queue = null; private UserQueue(){ queue = new LinkedBlockingDeque<User>(); } public static UserQueue getInstance(){ if(instance == null){ instance = new UserQueue(); } return instance; } /** * 取下一个员工 * @return */ public User takeNext(){ User user = null; try { user = queue.take(); this.put(user); } catch (InterruptedException e) { e.printStackTrace(); } return user; } /** * 将新员工放入队列中未尾 */ public void put(User user){ if(queue.contains(user)){ return; }else{ try { queue.put(user); } catch (InterruptedException e) { e.printStackTrace(); } } } public void putAll(Collection<User> users){ for(User user : users){ this.put(user); } } /** * 将已不存在的员工移除 */ public void remove(User user){ if(queue.contains(user)){ queue.remove(user); } } /** * 获取目前队列中所有的user * @return */ public Object[] getAllUsers(){ Object[] obj = queue.toArray(); return obj; } /** * @param args */ public static void main(String[] args) { User user1 = new User(); user1.setUid(1); user1.setAccount("11"); User user2 = new User(); user2.setUid(1); user2.setAccount("11"); User user3 = new User(); user3.setUid(3); user3.setAccount("11"); User user4 = new User(); user4.setUid(4); user4.setAccount("444"); User user5 = new User(); user5.setUid(5); user5.setAccount("555"); UserQueue.getInstance().put(user1); UserQueue.getInstance().put(user2); UserQueue.getInstance().put(user3); UserQueue.getInstance().put(user4); UserQueue.getInstance().put(user5); for(int i = 0 ; i < 20; i++){ System.out.println(UserQueue.getInstance().takeNext().getUid()); if(i == 5){ UserQueue.getInstance().remove(user2); } } Object[] users = UserQueue.getInstance().getAllUsers(); System.out.println("======="); for(Object user:users){ System.out.println(((User)user).getUid()); } } }
对于要实现User对象的比较,首先要重写equals方法.以下是我重写的User的equals方法
public boolean equals(Object obj) { if(!(obj instanceof User)){ return false; } User u = (User)obj; return (u.getAccount().equals(account) && u.getUid().equals(uid)); }
import java.util.List; import java.util.TimerTask; import org.apache.log4j.Logger; import com.cms.common.ServiceUtil; import com.cms.common.SysConfig; import com.cms.entity.ClientRecord; import com.cms.entity.User; import com.cms.service.ClientService; /** * 定时将客户意向放入任务队列 * 并且重新成功员工队列 * @author dg * */ public class GenerateTask extends TimerTask { private static Logger logger = Logger.getLogger(GenerateTask.class); private ClientService clientService = (ClientService)ServiceUtil.getService("clientService"); public void run() { try { String autoTaskRoleIds = SysConfig.getStrValue("autotask.roleid"); if(autoTaskRoleIds == null || autoTaskRoleIds.trim().equals("") || autoTaskRoleIds.split(",").length == 0){ logger.error("自动派单角色未设置"); return; } //取全部名单 List<User> userList = clientService.getAllAutoTaskUsers(autoTaskRoleIds.split(",")); if(userList == null || userList.size() == 0){ logger.error("目前还未有业务员无法派单"); return; } //将已不存在的用户移除 Object[] users = UserQueue.getInstance().getAllUsers(); for(Object user : users){ if(!userList.contains(user)){ UserQueue.getInstance().remove((User)user); } } //重新生成名单 UserQueue.getInstance().putAll(userList); //生成任务 List<ClientRecord> recordList = clientService.getAllUnAssignRecord(); TaskQueue.getInstance().putAll(recordList); } catch (Throwable t) { logger.error("自动派单任务异常!" ,t); }finally{ logger.info("此次任务执行完毕!"); } } }
import org.apache.log4j.Logger; import com.cms.common.ServiceUtil; import com.cms.entity.ClientRecord; import com.cms.entity.User; import com.cms.schedule.TaskQueue; import com.cms.schedule.UserQueue; import com.cms.service.ClientService; /** * 从任务队列里取到任务,自动派单给业务员 * @author dg * */ public class AutoDispatchTaskThread implements Runnable{ private static Logger logger = Logger.getLogger(AutoDispatchTaskThread.class); private ClientService clientService = (ClientService)ServiceUtil.getService("clientService"); private boolean stop = false; @Override public void run() { try{ while(!stop){ ClientRecord record = (ClientRecord)TaskQueue.getInstance().take(); User user = UserQueue.getInstance().takeNext(); clientService.assginRecord(record.getRid(), user.getUid()); } }catch(Throwable t){ logger.error(t.getMessage(),t); } } }