多线程之指定线程运行服务器

appliction-frame.xml配置

<!-- 应用服务器启动时,启动相应的线程 -->
	<bean id="appThreadStart" class="com.shareinfo.commons.thread.AppThreadStart">
		<!-- 可在多台服务器上同时运行的后台线程 -->
		<property name="multipleThreadObjects">
			<list>
				<value>com.shareinfo.commons.thread.multiple.MultipleCheckOnlineUser</value>
				<value>com.shareinfo.commons.thread.multiple.MultipleInitProperties</value>
				<value>com.shareinfo.commons.thread.multiple.MultipleLogOperation</value>
				<value>com.shareinfo.commons.thread.multiple.MultipleLogUserLogin</value>
				<value>com.shareinfo.commons.thread.multiple.MultipleCheckFixedScanOverdue</value>
			</list>
		</property>
		<!-- 只能在单台服务器上运行的后台线程 -->
		<property name="singleThreadObjects">
			<list>
				<!--
				<value>com.shareinfo.commons.thread.single.services.SingleSmsClient</value>
				<value>com.shareinfo.commons.thread.single.services.SingleEmailClient</value>
				-->
			</list>
		</property>
		<!-- 只能在单台服务器上运行的后台线程,在IP地址为这个的服务器上运行 -->
		<property name="singleIpAddress" value="192.168.1.163" />
	</bean>

 后台主线程,用于启动其他线程,这里使用Spring的InitializingBean的afterPropertiesSet()方法来初始化后台主线程,即web容器启动,取初始启动后台主线程

// 后台主线程,用于启动其他线程
@Log4j
public class AppThreadStart implements InitializingBean
{
	// 可在多台服务器上同时运行的后台线程
	@Setter
	private List multipleThreadObjects;

	// 只能在单台服务器上运行的后台线程
	@Setter
	private List singleThreadObjects;

	// 只能在单台服务器上运行的后台线程,在IP地址为这个的服务器上运行
	@Setter
	private String singleIpAddress;

	public void afterPropertiesSet() throws Exception
	{
		if (CollectionUtils.isNotEmpty(multipleThreadObjects))
		{
			Iterator iterator = multipleThreadObjects.iterator();
			while (iterator.hasNext())
			{
				Object object = iterator.next();
				start(object);
			}
		}

		String localHostAddress = NetworkUtils.localHostAddress();

		StringBuffer message = new StringBuffer();
		message.append("LocalHostAddress: " + localHostAddress);
		message.append(", SingleMachineIpAddress: " + singleIpAddress);
		log.info(message.toString());

		if (!StringUtils.equals(localHostAddress, singleIpAddress))
			return;

		if (CollectionUtils.isNotEmpty(singleThreadObjects))
		{
			Iterator iterator = singleThreadObjects.iterator();
			while (iterator.hasNext())
			{
				Object object = iterator.next();
				start(object);
			}
		}
	}

	private void start(Object object)
	{
		if (object == null)
			return;

		if (!(object instanceof String))
			return;

		String clazzName = (String)object;
		if (StringUtils.isEmpty(clazzName))
			return;

		try
		{
			Object thread = Class.forName(clazzName).newInstance();
			if (!(thread instanceof Runnable))
				return;

			new Thread((Runnable)thread).start();
			log.info("Thread [" + clazzName + "] is starting...");
		}
		catch (ClassNotFoundException e)
		{
			log.warn(clazzName + " isn't fund !!");
		}
		catch (InstantiationException e)
		{
			log.warn("InstantiationException: [" + clazzName + "] " + e.getMessage());
		}
		catch (IllegalAccessException e)
		{
			log.warn("IllegalAccessException: [" + clazzName + "] " + e.getMessage());
		}
		catch (Exception e)
		{
			log.warn("Exception: [" + clazzName + "] " + e.getMessage());
		}
	}
}

 线程抽象类:

public abstract class AbstractThread implements Runnable
{
	public abstract boolean isNullServiceBean();

	/**
	 * 休眠时间,以秒为单位
	 */
	protected void sleepSeconds(long l)
	{
		sleep(1000 * l);
	}

	/**
	 * 休眠时间,以分钟为单位
	 */
	protected void sleepMinuts(long l)
	{
		sleep(1000 * 60 * l);
	}

	/**
	 * 休眠时间,以毫秒为单位
	 */
	private void sleep(long l)
	{
		try
		{
			Thread.sleep(l);
		}
		catch (Exception e)
		{
		}
	}
}

 逾期定时扫描(多台服务器可运行):

/**
 * 定时检查逾期定时器是否执行成功
 * @ClassName: MultipleCheckFixedScanOverdue 
 * @Description: TODO 
 * @author xiaoqun.yi  [email protected]
 * @date 2015-9-1 下午02:36:37 
 * @version V1.0
 */
public class MultipleCheckFixedScanOverdue extends AbstractThread {

	private ITaskExecutionService taskExecutionService;

	private ISequenceService sequenceService;
	
	private NoticeTempToolProxy noticeTempToolProxy;
	
	public void run() {
		while (isNullServiceBean()) {
			try {
				if (taskExecutionService == null)
					taskExecutionService = (ITaskExecutionService) SpringUtils.getBean("taskExecutionService");
				
				if (sequenceService == null)
					sequenceService = (ISequenceService) SpringUtils.getBean("sequenceService");
				
				if (noticeTempToolProxy == null)
					noticeTempToolProxy = (NoticeTempToolProxy) SpringUtils.getBean("noticeTempToolProxy");
				
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				sleepSeconds(10);
			}
		}

		while (true) {
			try {
				TaskExecutionQuery taskExecutionQuery= new TaskExecutionQuery();
				taskExecutionQuery.setTaskType(TaskExecution.TaskType.overdueScan);
				taskExecutionQuery.setStatus("SUCCESS");
				taskExecutionQuery.setSmsFlag("N");
				taskExecutionQuery.setEmailFlag("N");
				Calendar cal=Calendar.getInstance();
				int hour=cal.get(Calendar.HOUR_OF_DAY);
				/**每天凌晨1点以后开始检查逾期定时器是否执行成功*/
				if(hour>=1){
					boolean overdueScanFlag=taskExecutionService.isExecutedDayTask(taskExecutionQuery);
					if(!overdueScanFlag){
						/**任务类型为逾期扫描检查*/
						taskExecutionQuery.setTaskType(TaskExecution.TaskType.overdueScanCheck);
						/**判断当天是否已经发送短信或者邮件*/
						taskExecutionQuery.setSmsFlag("Y");
						taskExecutionQuery.setEmailFlag("N");
						boolean smsFlag=taskExecutionService.isExecutedDayTask(taskExecutionQuery);
						taskExecutionQuery.setSmsFlag("N");
						taskExecutionQuery.setEmailFlag("Y");
						boolean emailFlag= taskExecutionService.isExecutedDayTask(taskExecutionQuery);
						/**如果没有发送短信或邮件*/
						if(!smsFlag||!emailFlag){
							TaskExecution taskExecution=new TaskExecution();
							taskExecution.setTaskType(TaskExecution.TaskType.overdueScanCheck);
							taskExecution.setTaskName("逾期定时扫描检查执行情况");
							taskExecution.setInsertBy("sys");//系统 
							if(!smsFlag){
								/**发送短信*/
								Map<String,Object> param=new HashMap<String, Object>();
								Map<String,Object> result=new HashMap<String, Object>();
								param.put("mobile", "18684894397");
								param.put("smsContent", "当天逾期定时器未成功执行,请手动执行并检查原因.");
								result=noticeTempToolProxy.sendSms(param);
								if(null!=result){
									Map<String,Object> statusResult=(Map<String, Object>) result.get("data");
									if(null!=statusResult&&statusResult.get("status").toString().equals("1")){
										taskExecution.setId(sequenceService.nextval(Sequence.SEQ_TASK_EXECUTION));
										taskExecution.setStatus("SUCCESS");
										taskExecution.setSmsFlag("Y");
										taskExecution.setEmailFlag("N");
										taskExecutionService.insert(taskExecution);
									}
								}
							}
							if(!emailFlag){
								/**发送邮件*/
								Map<String,Object> param=new HashMap<String, Object>();
								Map<String,Object> result=new HashMap<String, Object>();
								param.put("email", "[email protected]");
								param.put("emailContent", "当天逾期定时器未成功执行,请手动执行并检查原因.");
								result=noticeTempToolProxy.sendEmail(param);
								if(null!=result){
									Map<String,Object> statusResult=(Map<String, Object>) result.get("data");
									if(null!=statusResult&&statusResult.get("status").toString().equals("1")){
										taskExecution.setId(sequenceService.nextval(Sequence.SEQ_TASK_EXECUTION));
										taskExecution.setStatus("SUCCESS");
										taskExecution.setSmsFlag("N");
										taskExecution.setEmailFlag("Y");
										taskExecutionService.insert(taskExecution);
									}
								}
								
							}
						}
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			} finally {
				sleepMinuts(10);
			}
		}
	}

	/**
	 * 检查Service Bean是否加载完毕
	 */
	public boolean isNullServiceBean() {
		if (taskExecutionService == null)
			return true;
		
		if (sequenceService == null)
			return true;
		
		if (noticeTempToolProxy == null)
			return true;
		
		return false;
	}

}

 邮件发送客户端(单台服务器运行纯种):

public class SingleEmailClient extends AbstractThread
{
	private ILogEmailService logEmailService = null;

	public void run()
	{
		while (isNullServiceBean())
		{
			try
			{
				if (logEmailService == null)
					logEmailService = (ILogEmailService)SpringUtils.getBean("logEmailService");
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				sleepSeconds(10);
			}
		}

		// 查询短信列表中的进行发送
		while (true)
		{
			try
			{
				send();
			}
			catch (Exception e)
			{
				e.printStackTrace();
			}
			finally
			{
				sleepMinuts(1);
			}
		}
	}

	/**
	 * 检查Service Bean是否加载完毕
	 */
	public boolean isNullServiceBean()
	{
		if (logEmailService == null)
			return true;

		return false;
	}

	/**
	 * 检查待发送的邮件,并发送
	 */
	private void send()
	{
		LogEmailQuery query = new LogEmailQuery();
		query.setExpectSendTimeTo(DateUtils.currentTime("yyyy-MM-dd HH:mm:ss"));

		List<LogEmail> emailList = logEmailService.selectList(query, new Page(1, 200));
		if (CollectionUtils.isEmpty(emailList))
			return;

		List<String> successIdList = new ArrayList<String>();
		List<String> failIdList = new ArrayList<String>();
		for (LogEmail email : emailList)
		{
			if (NumberUtils.defaultInt(email.getSendTimes(), 0) >= 3)
			{
				List<String> list = Arrays.asList(new String[] { String.valueOf(email.getId()) });
				logEmailService.insertHis(list, IConstants.FAIL);
				continue;
			}

			String to = email.getMailTo();
			String subject = email.getSubject();
			String message = email.getMessage();

			String smtp = email.getSmtp();
			String user = email.getAuthUser();
			String password = email.getAuthPassword();
			String nick = email.getNick();
			String from = email.getMailFrom();

			EmailService emailService = new EmailService(smtp, user, password, nick, from, to);
			boolean isSuccess = emailService.send(subject, message);
			if (isSuccess)
				successIdList.add(String.valueOf(email.getId()));
			else
				failIdList.add(String.valueOf(email.getId()));
		}

		if (CollectionUtils.isNotEmpty(successIdList))
			logEmailService.insertHis(successIdList, IConstants.SUCCESS);

		if (CollectionUtils.isNotEmpty(failIdList))
			logEmailService.updateList(failIdList, IConstants.FAIL);
	}
}

 

你可能感兴趣的:(多线程之指定线程运行服务器)