`

使用线程实现“到点自动办理”

    博客分类:
  • Java
阅读更多

最近弄一功能,需要到点了自动办结日程。实现这个功能有两个办法,一个是使用线程,一个是使用数据库中的作业(SQL Server里面有作业,其他的数据库有木有不太清楚)。

 

基本思路是:在系统文件里配置俩变量:是否启动自动办结,自动办结时间。系统启动读取“是否自动办结”变量,若启动就开启一个线程。该线程不断获取当前时间,若当前时间与自动办结时间相同或在5分钟之内,就自动办结待办日程。

 

具体代码如下:

1、在配置文件中配置变量:

startAutoEnd:1 是否启动线程,设置为启动

autoEndTime:12:30 自动办结时间,这里设置为12点半(设置成12点也行)

 

2、系统启动时,添加代码是否启动线程:

Integer startAutoEnd=0;
if(WebAppConfig.app("startAutoEnd")!=null && !WebAppConfig.app("startAutoEnd").equals("")){
	startAutoEnd = Integer.parseInt(WebAppConfig.app("startAutoEnd"));
}
if(startAutoEnd==1){//说明开启自动办结
	Thread th = new Thread(new com.wjl.AutoEndThread(),"autoEnd");
	th.start();//启动线程
}
 

 3、AutoEndThread线程处理:

public class AutoEndThread implements Runnable {
	org.apache.log4j.Logger logger=Logger.getLogger(AutoEndThread.class);
	public void run() {
		autoEnd();
	}
	
	//日程记录自动办结
	private void autoEnd(){
		Integer startAutoEnd=0;
		String autoEndTime="";
		int hour=0,len=0,minite=0,sign=0,hour2=0,minite2=0;
		Calendar date = null;
		ExecSQL execSQL =null;
		StringBuffer sql =new StringBuffer();
		try {
			Thread.sleep(30000);//休眠半分钟,等待其他数据初始化完成
			execSQL = (ExecSQL) SpringApplicationContextHolder.getSpringBean("ExecSQL");//获取ExecSQL的bean
			while(true){
				//避免配置文件在项目启动过程中修改
				if(WebAppConfig.app("startAutoEnd")!=null && !WebAppConfig.app("startAutoEnd").equals("")){
					startAutoEnd = Integer.parseInt(WebAppConfig.app("startAutoEnd"));
				}
				if(startAutoEnd==1){//说明开启自动办结
					//获取系统设定的自动办结时间
					if(WebAppConfig.app("autoEndTime")!=null && !WebAppConfig.app("autoEndTime").equals("")){
						autoEndTime = WebAppConfig.app("autoEndTime");
					}
					
					if(autoEndTime!=null && !autoEndTime.equals("")){//说明有设置时间
						//变量初始化
						hour=0;
						len=0;
						minite=0;
						sign=0;
						sql.delete(0, sql.length());//清空StringBuffer
						
						//获取设置的时间
						len=autoEndTime.split(":").length;
						if(len<2){//说明没有冒号,那么只有时没有分
							autoEndTime = autoEndTime.replaceAll(":", "").replaceAll(":","");//替换冒号
							hour=Integer.parseInt(autoEndTime);
							minite=0;
						}else{
							hour = Integer.parseInt(autoEndTime.split(":")[0]);
							minite = Integer.parseInt(autoEndTime.split(":")[1]);
						}
						
						//获取当前时间
						date = Calendar.getInstance();
						hour2=date.get(Calendar.HOUR_OF_DAY);
						minite2= date.get(Calendar.MINUTE);
//						System.out.println(autoEndTime+"\n"+hour+"\n"+hour2+"\n"+minite+"\n"+minite2);
						if((hour==hour2 && minite==minite2) || ((hour==hour2 && (minite2>minite) && (minite2-minite)<=5))){//说明当前时间即为设置的处理时间(或者5分钟之内)
							sql.append("update S_TODOTASK set S_FINISH=1,S_FinishUserID=s.S_USER_ID,S_FinishDate=GETDATE(),S_FinishMemo='系统自动办结' ");
							sql.append("from  S_SCHEDULE s where s.S_ID = S_TODOTASK.S_TableKey ");
							sql.append("and S_TODOTASK.S_ModuleID=0 and S_TODOTASK.S_VALID=1 ");
							sql.append("and S_TODOTASK.S_FINISH=0 and S_TODOTASK.S_AUTOEND=1 "); 
							sql.append("and datediff(day,S_TODOTASK.S_PlannedDate,GETDATE())=0");
							
//							System.out.println("自动办结执行的SQL:"+sql.toString());
//							System.out.println("*******************************************************************************\n"+execSQL);
							sign = execSQL.execSQL(sql.toString());
							logger.debug("自动办结执行的SQL:"+sql.toString()+"\n执行结果:"+sign);
							Thread.sleep(30000);//休眠半分钟
						}
						
					}
				}
			}
			}catch (Exception e) {
				e.printStackTrace();
			}
	}
}
4、SpringApplicationContextHolder的getSpringBean()获取ExecSQL实例(ExecSQL实例需要在Spring的配置文件中进行配置):
public class SpringApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringApplicationContextHolder.context = context;
    }
    public static Object getSpringBean(String beanName) {
        return context==null?null:context.getBean(beanName);
    }
    public static String[] getBeanDefinitionNames() {
        return context.getBeanDefinitionNames();
    }
}
 

 5、ExecSQL中的execSQL方法用来执行SQL语句:

/***
 * 执行sql语句,insert、update、delete
 * 
 * @param sql
 * @return 1-成功,0-失败
 */
public int execSQL(final String sql) throws Exception{
	log.debug("执行sql语句: " + sql);
	try {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session)
							throws HibernateException, SQLException {
			return session.createSQLQuery(sql).executeUpdate();
		}
	});
	} catch (Exception re) {
		log.info("执行sql:[" + sql + "]失败:" + re.getMessage());
		log.error("执行sql:[" + sql + "]失败:" + re.getMessage(), re);
		throw re;
	}
}

 

6、说明:

项目中的ExcelSQL实例是直接从Spring的实例中获取的,而不是直接New对象或者通过Spring重新注册获取,原因在于:

a、直接New:ExcelSQL对象不会为空,但是getHibernateTemplate()对象为空。

b、使用Spring注册ExcelSQL,ExcelSQL对象为空。

最后就剩下直接从Spring中取ExcelSQL实例了。

分享到:
评论

相关推荐

    PB多线程实现

    1. **线程安全**:确保共享数据在多线程环境下正确访问,通常需要使用锁(如Monitor或Mutex)、信号量(Semaphore)或原子操作来实现。 2. **线程间通信**:线程间的同步和通信至关重要,可以使用事件(Event)、...

    ui自动化多线程+聚合报告

    `run_test_Multithreading.py`很可能是一个实现了多线程测试的Python脚本,它可能使用了Python的`threading`库或者第三方库如`concurrent.futures`来实现并发执行。 **聚合报告** 是一种将多个独立测试的结果汇总...

    Android----线程实现图片移动

    本主题将探讨如何利用线程技术实现图片在屏幕上的水平循环往返移动。线程在Android中扮演着处理后台任务的重要角色,它可以避免因为长时间运行操作而阻塞主线程,确保UI的流畅性。 首先,我们需要理解Android的线程...

    QT/C++ TCP多线程客户端(收发线程分离,自动粘包处理,自动数据包成型)

    因此,通过使用多线程,我们可以将接收和发送操作分离开,以提高系统的并行处理能力。 1. **多线程模型**:在本项目中,采用了两种线程来处理不同的任务——一个用于接收数据,另一个用于发送数据。这种设计可以...

    Qt 使用多线程QThread实现进度条

    我们可以通过继承QThread并重写run()方法来实现自定义的工作线程逻辑。但是,值得注意的是,QThread并不直接管理对象的生命周期,因此通常不建议在run()方法中直接创建和销毁对象。更好的做法是使用信号和槽机制,...

    MFC中利用多线程实现定时器

    其中,多线程技术可以用于实现复杂的并发操作,包括创建定时器功能。本篇文章将详细探讨如何在MFC中利用多线程来实现定时器。 首先,我们需要了解MFC中的`CWinThread`类,它是所有线程的基础类。创建一个新的线程时...

    java多线程实现TCP连接UDP聊天的聊天程序

    java多线程实现TCP连接UDP聊天的聊天程序

    windows环境下C语言多线程实现网络编程,多人聊天室,[总结].pdf

    在 Windows 环境下实现多人聊天室需要使用 C 语言和多线程技术来实现网络编程。下面是关于这个主题的知识点总结: 第一部分:Windows Socket 编程 * 使用 `winsock2.h` 头文件来实现 Windows Socket 编程 * 使用 `...

    DELPHI7 线程自动刷新

    "DELPHI7 线程自动刷新"这个主题涉及到的是如何在Delphi 7中使用线程来实现数据或界面的自动更新,以提高程序的响应性和用户体验。 在Delphi 7中,创建线程通常是通过继承自TThread类来完成的。TThread是VCL...

    C#实现多线程下载文件

    线程池可以自动管理和重用线程,减少创建和销毁线程的开销。要使用线程池,可以调用`ThreadPool.QueueUserWorkItem`方法,传入一个委托(Action或Func),代表要在线程中执行的任务。 对于文件下载,我们可以定义一...

    用VB6实现多线程

    要实现在VB6中创建线程,我们需要了解和使用以下API函数: 1. **CreateThread**:这是Windows API中的一个函数,用于创建新的线程。它的原型为: ```vb Declare Function CreateThread Lib "kernel32" (ByVal ...

    线程自动运行模板很好

    "线程自动运行模板"是一种设计模式,它使得开发者能够更方便地管理和控制线程的生命周期,无需手动启动和停止,简化了线程的使用。 线程自动运行模板通常包含以下几个关键部分: 1. **线程类**:这是实现特定任务...

    java多线程网络编程实现ATM自动取款机系统

    Java多线程网络编程在实现ATM自动取款机系统中的应用主要涉及到以下几个核心知识点: 1. **Java多线程**:多线程是Java语言的重要特性,它允许多个任务在同一时间执行,提高程序效率。在ATM系统中,每个用户操作...

    C# 不使用Task实现的多线程顺序执行

    在某些特殊情况下需要用到多线程然而又要使其具备顺序性,这种时候就有了一个特殊的场景那就是多线程顺序执行,在现在VS2015中Task自带了顺序执行的方法,但在此之前的旧项目中如果需要使用多线程顺序执行该怎么办呢...

    C# 通过委托和线程实现chart控件的实时更新

    为此,我们可以使用委托(Delegate)和线程(Thread)来实现这个功能。在本文中,我们将详细介绍如何使用委托和线程来实现 Chart 控件的实时更新。 委托(Delegate) 在 C# 中,委托是一个类型安全的引用,可以...

    利用VB6实现多线程

    本篇主要介绍如何利用VB6实现多线程,以及涉及的关键概念和技术。 一、多线程概念 多线程是指在一个应用程序中存在多个并行执行的线程,它们共享同一内存空间,但各自拥有独立的执行流。通过多线程,可以实现任务的...

    C#后台多线程实现自动采集指定网页上面指定标签新闻

    在本项目“C#后台多线程实现自动采集指定网页上面指定标签新闻”中,开发者利用C#语言的特性,创建了一个能够后台运行的新闻采集系统。这个系统能够高效地从设定的网站上抓取指定标签的新闻内容,包括图片、文字等...

    线程内使用SetTimer实现定时器

    本篇将详细讲解如何在线程内部使用`SetTimer`来实现定时器,以及`MyThreadTimer`的实现方式。 首先,理解`SetTimer`函数的基本用法。`SetTimer`的原型如下: ```cpp UINT_PTR SetTimer( _In_opt_ HWND hWnd, _In...

    VB 实现多线程

    - **线程安全**:确保所有被多线程使用的变量都已经声明,避免使用隐式声明。 - **资源释放**:当线程完成时,确保释放所有资源,包括关闭窗口等操作。 #### 四、解决退出时的问题 **问题描述**:退出应用程序时,...

    pb多线程实现的例程

    - 启动线程:调用Thread对象的start()方法,系统会自动调用run()方法执行任务。 - 线程控制:包括join()(等待线程执行完毕)、interrupt()(中断线程)和yield()(让出CPU执行权)等方法。 4. **线程同步与通信*...

Global site tag (gtag.js) - Google Analytics