java中怎么实现定时功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java中怎么实现定时功能相关的知识,希望对你有一定的参考价值。

每过5秒钟就输入“hello,Java”

这个是我在网上找的不知道是不是你要的:

java定时任务Timer 关于定时任务,似乎跟时间操作的联系并不是很大,但是前面既然提到了定时任务,索性在这里一起解决了。设置定时任务很简单,用Timer类就搞定了。一、延时执行首先,我们定义一个类,给它取个名字叫TimeTask,我们的定时任务,就在这个类的main函数里执行。代码如下:
package test;
import java.util.Timer;
public class TimeTaskTest
public static void main(String[] args) Timer timer = new Timer();
timer.schedule(new Task(), 60 * 1000);


解释一下上面的代码。上面的代码实现了这样一个功能,当TimeTask程序启动以后,过一分钟后执行某项任务。很简单吧:先new一个Timer对象,然后调用它的schedule方法,这个方法有四个重载的方法,这里我们用其中一个,
public void schedule(TimerTask task,long delay)
首先,第一个参数第一个参数就是我们要执行的任务。这是一个TimerTask对象,确切点说是一个实现TimerTask的类的对象,因为TimerTask是个抽象类。上面的代码里 面,Task就是我们自己定义的实现了TimerTask的类,因为是在同一个包里面,所以没有显性的import进来。Task类的代码如下
package test;
import java.util.TimerTask;
public class Task extends TimerTask public void run()

System.out.println("定时任务执行");


我们的Task必须实现TimerTask的方法run,要执行的任务就在这个run方法里面,这里,我们只让它往控制台打一行字。第二个参数第二个参数是一个long型的值。这是延迟的时间,就是从程序开始以后,再过多少时间来执行定时任务。这个long型的值是毫秒数,所以前面我们的程序里面,过一分钟后执行用的参数值就是 60 * 1000。二、循环执行设置定时任务的时候,往往我们需要重复的执行这样任务,每隔一段时间执行一次,而上面的方法是只执行一次的,这样就用到了schedule方法的是另一个重载函数public void schedule(TimerTask task,long delay,long period)
前两个参数就不用说什么了,最后一个参数就是间隔的时间,又是个long型的毫秒数(看来java里涉及到时间的,跟这个long是脱不了干系了),比如我们希望上面的任务从第一次执行后,每个一分钟执行一次,第三个参数值赋60 * 1000就ok了。三、指定执行时间既然号称是定时任务,我们肯定希望由我们来指定任务指定的时间,显然上面的方法就不中用了,因为我们不知道程序什么时间开始运行,就没办法确定需要延时多少。没关系,schedule四个重载的方法还没用完呢。用下面这个就OK了:
public void schedule(TimerTask task,Date time)
比如,我们希望定时任务2006年7月2日0时0分执行,只要给第二个参数传一个时间设置为2006年7月2日0时0分的Date对象就可以了。有一种情况是,可能我们的程序启动的时候,已经是2006年7月3日了,这样的话,程序一启动,定时任务就开始执行了。schedule最后一个重载的方法是public void schedule(TimerTask task,Date firstTime,long period)
没必要说什么了吧:)四、j2ee中的定时任务在实际的项目中,往往定时任务需要对web工程中的资源进行操作,这样一来,用上面的单个程序的方式可能就有点力不从心了,因为很多web工程的资源它操作不到。解决的办法是,使用Servlet,把执行定时任务的那些代码放到Servlet的init()函数里就可以了,这个easy,就没有必要再写示例代码了吧
参考技术A 我们可以使用Timer和TimerTask类在java中实现定时任务,详细说明如下:

1、基础知识
java.util.Timer
一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。此类是线程安全的:多个线程可以共享单个 Timer 对象而无需进行外部同步。
java.util.TimerTask
由 Timer 安排为一次执行或重复执行的任务。

2、示例代码
该示例实现这样一个功能,在系统运行期间,每30分钟,系统自动检查连接池中的可用连接数,并输出到日志中。
首先创建一个需要定时执行的任务类,这个任务类需要继承TimerTask,然后重写run()方法,run()方法体中的代码就是定时需要执行的操作,在本demo中,就是获取连接池中当前可用连接数,并输出到日志中,具体实现代码如下:
public class TaskAvailableConnectNumber extends TimerTask
private Logger log = Logger.getLogger(TaskAvailableConnectNumber.class);
private ConnectionPool pool=ConnectionPool.getInstance();
@Override
publicvoid run()
log.debug("当前连接池中可用连接数"+pool.getAvailableConnectNumber());


下面定义一个监听器,负责在应用服务器启动时打开定时器,监听器需要实现ServletContextListener接口,并重写其中的contextInitialized()和contextDestroyed()方法,代码如下:
public class OnLineListener implements ServletContextListener
private Logger log = Logger.getLogger(OnLineListener.class);
Timer timer = null;
//在应用服务器启动时,会执行该方法
publicvoid contextInitialized(ServletContextEvent arg0)
//创建一个定时器,用于安排需要定时执行的任务。
timer = new Timer();
//为定时器安排需要定时执行的任务,该任务就是前面创建的任务类TaskAvailableConnectNumber,并指定该任务每30分钟执行一次。
timer.schedule(new TaskAvailableConnectNumber(), 0, 30*60*1000);
log.debug("启动定时器");

//应用服务器关闭时,会执行该方法,完成关闭定时器的操作。
public void contextDestroyed(ServletContextEvent arg0)
if(timer!=null)
timer.cancel();//关闭定时器
log.debug("-----定时器销毁--------");



监听器要想正常运行,需要在web.xml文件中进行配置,配置信息如下:
<!-- 监听器配置开始 -->
<listener>
<listener-class>
cn.sdfi.listen.OnLineListener
</listener-class>
</listener>
<!-- 监听器配置结束 -->
以上步骤完成后,一个简单的定时器就算开发完成了。
参考技术B 恢复一下出厂设置

愚人节专场Java实现定时发送小情话

首先,感谢大佬的帮助~附上大佬的博客以示尊敬https://blog.csdn.net/qq_38591577/article/details/128164308?spm=1001.2014.3001.5502

功能实现:

在名为愚人节,实为告白/情人节的日子里,怎么样才能引起TA的关注呢?不妨试着定时发送(土味)小情话来增进感情呢~

我的老婆们收到之后都开心的表示,不要捣鼓这些无聊的东西,不如抓紧去赚钱。

这是来自老婆的反馈:

 

 

 

咳咳,虽然被针对了,但是女人说不要那就是要(/▽\)

框架设计:

2.1 创建springboot项目

此处注意尽量不要使用springboot3.0.0,我这里用的是2.7.10。

2.2 pom依赖

<!-- hutool 依赖-->
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>4.3.2</version>
    </dependency>
<!-- 邮件 依赖 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
        <version>2.4.3</version>
    </dependency>

2.3 application.yml (配置文件)

spring:
  mail:
    host: smtp.qq.com                  #邮箱发送服务器
    username: 181*******@qq.com       #邮箱地址
    password: abdsjszkazkjsad       #获取邮箱第三方使用秘钥
    protocol: smtp
    properties.mail.smtp.port: 25       #端口
    default-encoding: utf-8
she:
  mail: 114*******@qq.com
  mail2: 184*******@qq.com
  mail3: 182*******@qq.com

2.4 DemoApplication启动类

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableScheduling
public class DemoApplication 

    public static void main(String[] args) 
        SpringApplication.run(DemoApplication.class, args);
    


2.5 SendMailService.java (接口)

package com.example.demo.service.impl;

import org.springframework.stereotype.Service;
@Service
public interface SendMailService 
    void sendMessage(String sub, String message);

    String getLovePrattle();

    String getWeather();


2.6 SendMail.java (接口实现类)

package com.example.demo.service.impl;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sun.xml.internal.messaging.saaj.packaging.mime.MessagingException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.mail.internet.MimeMessage;
import java.util.ArrayList;


@Component
public class SendMail implements SendMailService
    @Resource
    private JavaMailSender mailSender;

    @Value("$spring.mail.username")
    private String from;

    @Value("$she.mail")
    private String[] sheMail;
    @Value("$she.mail2")
    private String[] sheMail2;
    @Value("$she.mail3")
    private String[] sheMail3;


    public void sendMessage(String subject,String message) 
        ArrayList<String[]> objects = new ArrayList<>();
        objects.add(sheMail);
        objects.add(sheMail2);
        objects.add(sheMail3);

        for (String[] object : objects) 
        try 
            MimeMessage mimeMessage = mailSender.createMimeMessage();
            MimeMessageHelper helper = new MimeMessageHelper(mimeMessage);
            helper.setFrom(from);       //发送方邮件名
            helper.setTo(object);         //接收方邮件地址
            helper.setSubject(subject);     //邮件标题
            helper.setText(message,true);   //邮件内容,是否为html格式
            mailSender.send(helper.getMimeMessage());
         catch (javax.mail.MessagingException e) 
            e.printStackTrace();
        
    
    @Override
    public String getLovePrattle() 
        String result1= HttpUtil.get("https://api.lovelive.tools/api/SweetNothings");
        System.out.println(result1);
        return result1;
    

    //  实时天气
    @Override
    public String getWeather() 
        StringBuffer sb = new StringBuffer();
        String s = HttpUtil.get("https://devapi.qweather.com/v7/weather/now?location=101190113&key=f5fe849feaf24a60b54e6d6cb7062a8e");
        JSONObject jsonObject = JSONUtil.parseObj(s);
        System.out.println("时间为:"+jsonObject.get("updateTime"));
        sb.append("<p>时间为:"+jsonObject.get("updateTime")+"<br>\\n");
        System.out.println("详细天气请查看"+jsonObject.get("fxLink"));
        sb.append("详细天气请查看"+jsonObject.get("fxLink")+"<br>\\n");
        Object now = jsonObject.get("now");
        JSONObject nowJson = JSONUtil.parseObj(now);
        System.out.println("当前温度为"+nowJson.get("temp")+"℃");
        sb.append("当前温度为"+nowJson.get("temp")+"℃"+"<br>\\n");
        System.out.println("天气状况为"+nowJson.get("text"));
        sb.append("天气状况为"+nowJson.get("text")+"<br>\\n");
        System.out.println("风力等级"+nowJson.get("windScale")+"级");
        sb.append("风力等级"+nowJson.get("windScale")+"级"+"<br>\\n");
        System.out.println("能见度"+nowJson.get("vis")+"公里");
        sb.append("能见度"+nowJson.get("vis")+"公里</p >");
        String weater = sb.toString();
        return weater;
    


2.7 SchedueTask.java (定时任务配置类)

package com.example.demo.config;

import com.example.demo.service.impl.SendMail;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;

import javax.annotation.Resource;

@Configuration      //主要用于标记配置类,兼备Component的效果。
@EnableScheduling   // 开启定时任务
public class ScheduleTask 
    @Resource
    SendMail sendMail;

    @Async
    @Scheduled(cron = "0 */1 * * * ?")//每分钟发一次(这里是用的是cron表达式,可以上网查阅)
    public void send()
//        土味情话
        String one = sendMail.getLovePrattle();
//        String weather = sendMail.getWeather();

        sendMail.sendMessage("小点心",one);


    

总结:

试着实现了两个方法,一个调用天气,一个土味小情话。

当然,如果鱼塘里有好好多的好多鱼的话,也可以在配置文件里编辑多个邮箱,实现的时候for循环一下就可以了~~

QQ邮箱里的password一栏需要在QQ邮箱里进行设置。

 

由于我们配置的是SMTP,所以需要将其设置为打开

 

 

以上是关于java中怎么实现定时功能的主要内容,如果未能解决你的问题,请参考以下文章

PHP怎么实现定时提醒功能

Java定时任务:利用java Timer类实现定时执行任务的功能

在java中如何让定时器只启动一次?

Spring Boot 定时任务 @Scheduled

java 定时器

如何用 Java 实现 Web 应用中的定时任务