java 实现自动派单(自动分配任务)

需求:

最近要实现一个自动派单功能,就是如果有任务来了,那么任务平均分配给现有的员工,如果之前取了任务的员工下次来任务时就分配给下一个,如果有新员工则将员工添加到队列的最后,如果有员工离职就将员工信息从队列里移除。

实现:

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);
		}
	}
}

猜你喜欢

转载自yiding-123.iteye.com/blog/2099891