Java定时调度任务详解之Timer篇

简单介绍

什么是定时任务调度
    基于给定的时间点,给定的时间间隔,或者给定的执行次数自动执行的任务。
Java中定时调度工具
    Timer  ---〉 jdk
    Quartz --〉 第三方jar包,实现更完善。
    尽量使用jdk提供的timer

Timer简介

    有且仅有一个后台线程对多个业务线程进行定时定频率的调度。
主要构件

    Timer 可以理解为每个后台执行的线程,TimerTask业务线程



Timer工具类详解
第一个简单实例
[java]  view plain  copy
  1. import java.util.TimerTask;  
  2.   
  3. public class MyTaskTimer extends TimerTask {  
  4.       
  5.     private String name;  
  6.       
  7.     public MyTaskTimer(String name) {  
  8.         this.name = name;  
  9.     }  
  10.   
  11.     @Override  
  12.     public void run() {  
  13.             System.out.println("Current name is: " + name);  
  14.     }  
  15.   
  16.     public String getName() {  
  17.         return name;  
  18.     }  
  19.   
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24. }  
测试类
[java]  view plain  copy
  1. import java.util.Timer;  
  2.   
  3. public class MyTimer {  
  4.   
  5.     public static void main(String[] args) {  
  6.         // 1、创建一个Timer实例  
  7.         Timer timer = new Timer();  
  8.         //2、创建一个MyTimerTask实例  
  9.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  10.         //3、通过timer定时定频率调用myTimerTask的业务逻辑  
  11.         // 即第一次执行是在当前时间的两秒之后,之后每隔一秒钟执行一次  
  12.         timer.schedule(myTaskTimer, 2000L, 1000L);  
  13.     }  
  14.       
  15. }  

Timer的定时调度函数

schedule(task, time)
    task --> 所要安排的任务
    在时间等于或超过time的时候执行且仅执行一次task
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.TimerTask;  
  4.   
  5. public class MyTaskTimer extends TimerTask {  
  6.   
  7.     private String name;  
  8.   
  9.     public MyTaskTimer(String name) {  
  10.         this.name = name;  
  11.     }  
  12.   
  13.     @Override  
  14.     public void run() {  
  15.         Calendar calendar = Calendar.getInstance();  
  16.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  17.         System.out.println("current exect time:" + sf.format(calendar.getTime()));  
  18.         System.out.println("Current name is: " + name);  
  19.     }  
  20.   
  21.     public String getName() {  
  22.         return name;  
  23.     }  
  24.   
  25.     public void setName(String name) {  
  26.         this.name = name;  
  27.     }  
  28.   
  29. }  

测试类
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
  13.         /** 
  14.          * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  15.          */  
  16.         Calendar calendar = Calendar.getInstance();  
  17.                 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.         System.out.println(sf.format(calendar.getTime()));  
  19.         calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间  
  20.           
  21.         myTaskTimer.setName("schedule1");  
  22.         timer.schedule(myTaskTimer, calendar.getTime());  
  23.     }  
  24.       
  25. }  
schedule(task, time, period)
    task     --> 所要安排的任务
    time     -->首次执行任务的时间
    period  -->执行一次task的时间间隔,单位是毫秒
    时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
测试类
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
  13.         /** 
  14.          * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  15.          */  
  16.         Calendar calendar = Calendar.getInstance();  
  17.                 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.         System.out.println(sf.format(calendar.getTime()));  
  19.         calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间  
  20.           
  21.         myTaskTimer.setName("schedule2");  
  22.         timer.schedule(myTaskTimer, calendar.getTime(), 2000);//执行3秒钟之后的时间  
  23.     }  
  24.       
  25. }  

schedule(task, delay)
    task   --> 所要安排的任务
    delay --> 执行任务前的延时时间,单位毫秒
    等待delay毫秒后执行且仅执行一次task
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
  13.         /** 
  14.          * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  15.          */  
  16.         Calendar calendar = Calendar.getInstance();  
  17.                 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.         System.out.println(sf.format(calendar.getTime()));  
  19.         calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间  
  20.           
  21.         myTaskTimer.setName("schedule3");  
  22.         timer.schedule(myTaskTimer, 2000);//执行3秒钟之后的时间  
  23.     }  
  24.       
  25. }  
schedule(task, delay, period)
    task   --> 所要安排的任务
    delay --> 执行任务前的延时时间,单位毫秒
    period  -->执行一次task的时间间隔,单位是毫秒
    等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
[java]  view plain  copy
  1. /** 
  2.  * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  3.  */  
  4.   
  5. myTaskTimer.setName("schedule4");  
  6. Calendar calendar = Calendar.getInstance();  
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");System.out.println(sf.format(calendar.getTime()));calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间myTaskTimer.setName("schedule4");timer.schedule(myTaskTimer, 2000, 2000);//执行3秒钟之后的时间}}
 
  
scheduleAtFixedRate的两种用法
scheduleAtFixedRate(task, time, period)
    task     --> 所要安排的任务
    time     -->首次执行任务的时间
    period  -->执行一次task的时间间隔,单位是毫秒
    时间等于或超过time时首次执行task,之后每隔period毫秒重复执行一次task
 
  
 
  
 
  
 
 
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
  13.         /** 
  14.          * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  15.          */  
  16.         Calendar calendar = Calendar.getInstance();  
  17.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.         System.out.println(sf.format(calendar.getTime()));  
  19.         calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间  
  20.           
  21.         myTaskTimer.setName("scheduleAtFixedRate1");  
  22.         timer.scheduleAtFixedRate(myTaskTimer, calendar.getTime(), 2000);//执行3秒钟之后的时间  
  23.     }  
  24.       
  25. }  
scheduleAtFixedRate(task, delay, period)
    task   --> 所要安排的任务
    delay --> 执行任务前的延时时间,单位毫秒
    period  -->执行一次task的时间间隔,单位是毫秒
    等待delay毫秒后首次执行task,之后每隔period毫秒重复执行一次task
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
  13.         /** 
  14.          * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  15.          */  
  16.         Calendar calendar = Calendar.getInstance();  
  17.                 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.         System.out.println(sf.format(calendar.getTime()));  
  19.         calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间  
  20.           
  21.         myTaskTimer.setName("scheduleAtFixedRate2");  
  22.         timer.scheduleAtFixedRate(myTaskTimer, 30002000);//距离当前时间3秒钟  
  23.     }  
  24.       
  25. }  

其它重要函数

cancel()
取消当前TimerTask里的任务
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.TimerTask;  
  4.   
  5. public class MyTaskTimer extends TimerTask {  
  6.   
  7.     private String name;  
  8.       
  9.     private Integer count = 0;  
  10.   
  11.     public MyTaskTimer(String name) {  
  12.         this.name = name;  
  13.     }  
  14.   
  15.     @Override  
  16.     public void run() {  
  17.         if (count < 3) {  
  18.             Calendar calendar = Calendar.getInstance();  
  19.                     SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  20.                     System.out.println("current exect time:" + sf.format(calendar.getTime()));  
  21.             System.out.println("Current name is: " + name);   
  22.             count ++;  
  23.         } else {  
  24.             cancel();  
  25.             System.out.println("Task Cancle");  
  26.         }  
  27.           
  28.     }  
  29.   
  30.     public String getName() {  
  31.         return name;  
  32.     }  
  33.   
  34.     public void setName(String name) {  
  35.         this.name = name;  
  36.     }  
  37.   
  38. }  
测试类
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
  13.         /** 
  14.          * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  15.          */  
  16.         Calendar calendar = Calendar.getInstance();  
  17.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.         System.out.println(sf.format(calendar.getTime()));  
  19.         calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间  
  20.           
  21.         myTaskTimer.setName("schedule");  
  22.         timer.schedule(myTaskTimer, 30002000);//距离当前时间3秒钟  
  23.     }  
  24.       
  25. }  
scheduleExecutionTime()
    返回此任务最近实际执行的已安排执行的时间,返回值为最近发生此任务执行安排的时间,为long型
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class MyTimer {  
  6.   
  7.     public static void main(String[] args) {  
  8.         // 1、创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //2、创建一个MyTimerTask实例  
  11.         MyTaskTimer myTaskTimer = new MyTaskTimer("No 1");  
  12.           
  13.         /** 
  14.          * 获取当前时间,并设置成距离当前时间三秒之后的时间 
  15.          */  
  16.         Calendar calendar = Calendar.getInstance();  
  17.                 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  18.         System.out.println(sf.format(calendar.getTime()));  
  19.         calendar.add(Calendar.SECOND, 3);//设置三秒之后的时间  
  20.           
  21.         myTaskTimer.setName("schedule");  
  22.         timer.schedule(myTaskTimer, 3000);//距离当前时间3秒钟,只执行一次  
  23.           
  24.         System.out.println("schedule time is :" + sf.format(myTaskTimer.scheduledExecutionTime()));  
  25.     }  
  26.       
  27. }  

Timer下的cancel()
    终止此计时器,丢弃所有当前已安排的任务

实例:
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Date;  
  3. import java.util.Timer;  
  4.   
  5. public class CancleTest {  
  6.   
  7.     public static void main(String[] args) throws InterruptedException {  
  8.         //创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //创建TaskTimer实例  
  11.         MyTaskTimer task1 = new MyTaskTimer("task1");  
  12.         MyTaskTimer task2 = new MyTaskTimer("task2");  
  13.         //获取当前时间并打印  
  14.         Date startDate = new Date();  
  15.                 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  16.         System.out.println("start time is :" + sf.format(startDate));  
  17.           
  18.         timer.schedule(task1, 3000L, 2000L);  
  19.         timer.schedule(task2, 1000L, 2000L);  
  20.         //休眠5秒  
  21.         Thread.sleep(5000L);  
  22.         //获取当前时间并打印  
  23.         Date cancelTime = new Date();  
  24.         System.out.println("cancel time is :" + sf.format(cancelTime));  
  25.         //取消所有任务  
  26.         timer.cancel();  
  27.         System.out.println("Tasks all canceled");  
  28.     }  
  29. }  
Timer下的purge()
从此计时器的任务队列中移除所有已取消的任务,返回值 从队列中移除的任务数
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Date;  
  3. import java.util.Timer;  
  4.   
  5. public class CancleTest {  
  6.   
  7.     public static void main(String[] args) throws InterruptedException {  
  8.         //创建一个Timer实例  
  9.         Timer timer = new Timer();  
  10.         //创建TaskTimer实例  
  11.         MyTaskTimer task1 = new MyTaskTimer("task1");  
  12.         MyTaskTimer task2 = new MyTaskTimer("task2");  
  13.         //获取当前时间并打印  
  14.         Date startDate = new Date();  
  15.                 SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  16.         System.out.println("start time is :" + sf.format(startDate));  
  17.           
  18.         timer.schedule(task1, 3000L, 2000L);  
  19.         timer.schedule(task2, 1000L, 2000L);  
  20.         System.out.println("current canceled task number is:" + timer.purge());  
  21.         //休眠2秒  
  22.         Thread.sleep(2000L);  
  23.         //获取当前时间并打印  
  24.         Date cancelTime = new Date();  
  25.         System.out.println("cancel time is :" + sf.format(cancelTime));  
  26.         //取消task2的任务  
  27.         task2.cancel();  
  28.         System.out.println("current canceled task number is:" + timer.purge());  
  29.     }  
  30. }  

schedule和scheduleAtFixRate区别

schedule方法
    “fixed-delay” ;如果第一次执行时间被delay,随后的执行时间按照上一次实际完成的时间点进行计算.
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. public class DifferenceTest {  
  7.   
  8.     public static void main(String[] args) {  
  9.         final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  10.         Calendar calendar = Calendar.getInstance();  
  11.         System.out.println("current time is : " + sf.format(calendar.getTime()));  
  12.         //设置成6秒的时间,若当前时间为2017-11-11 00:00:06  
  13.         //那么设置之后的时间变成2017-11-11 00:00:00  
  14.         calendar.add(Calendar.SECOND, -6);  
  15.         Timer timer = new Timer();  
  16.         //第一次执行时间为6秒前,之后每隔两秒钟执行一次  
  17.         timer.schedule(new TimerTask() {  
  18.               
  19.             @Override  
  20.             public void run() {  
  21.                 //打印当前计划执行时间  
  22.                 System.out.println("schedule exect time is:" + sf.format(scheduledExecutionTime()));  
  23.                 System.out.println("Task is being exected");  
  24.             }  
  25.         },calendar.getTime(), 2000L);  
  26.     }  
  27. }  

scheduleAtFixRate方法
    “fixed-rate” ;如果第一次执行时间被delay了,随后的执行时间按照上一次开始的时间点进行计算,并且为了赶上进度会多次执行任务,因此TimerTask中的执行体需要考虑同步

任务执行时间超出执行时间间隔
schedule方法
    下一次执行时间相对于上一次实际执行完成的是时间点,因此执行时间会不断延后。
实例
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4. import java.util.TimerTask;  
  5.   
  6. public class DifferenceTest {  
  7.   
  8.     public static void main(String[] args) {  
  9.         final SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  10.         Calendar calendar = Calendar.getInstance();  
  11.         System.out.println("current time is : " + sf.format(calendar.getTime()));  
  12.         Timer timer = new Timer();  
  13.         timer.schedule(new TimerTask() {  
  14.               
  15.             @Override  
  16.             public void run() {  
  17.                 try {  
  18.                     Thread.sleep(3000L);  
  19.                 } catch (InterruptedException e) {  
  20.                     e.printStackTrace();  
  21.                 }  
  22.                 //打印当前计划执行时间  
  23.                 System.out.println("schedule exect time is:" + sf.format(scheduledExecutionTime()));  
  24.                 System.out.println("Task is being exected");  
  25.             }  
  26.         },calendar.getTime(), 2000L);  
  27.     }  
  28. }  
scheduleAtFixRate方法
    下一次执行时间相对于上一次开始的时间点,因此执行时间不会延后,因此存在并发性。

实际应用

[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.TimerTask;  
  3. /** 
  4.  * 跳舞机器人,每隔两秒钟跳舞 
  5.  */  
  6. public class DancingRobot extends TimerTask {  
  7.   
  8.     @Override  
  9.     public void run() {  
  10.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  11.         System.out.println("Scheduled exec time is : "  
  12.                 + sf.format(scheduledExecutionTime()));  
  13.         System.out.println("Dancing happily");  
  14.     }  
  15.   
  16. }  
[java]  view plain  copy
  1. import java.util.Timer;  
  2. import java.util.TimerTask;  
  3. /** 
  4.  * 灌水机器人,水注入满5升后,等待两秒钟后,取消所有 
  5.  * @author lijingyu 
  6.  * 
  7.  */  
  8. public class WaterRobot extends TimerTask {  
  9.   
  10.     private Timer timer;  
  11.     private Integer bucketCapacity = 0;  
  12.       
  13.     public WaterRobot(Timer inputTimer) {  
  14.         timer = inputTimer;  
  15.     }  
  16.       
  17.     @Override  
  18.     public void run() {  
  19.   
  20.         if (bucketCapacity < 5) {  
  21.             System.out.println("Add 1L water into the bucket!");  
  22.             bucketCapacity ++;  
  23.         } else {  
  24.             System.out.println("The number of canceled task in timer is :" + timer.purge());  
  25.             //水满后停止  
  26.             cancel();  
  27.             System.out.println("The WaterRobot has bean aborted!");  
  28.             System.out.println("The number of canceled task in timer is :" + timer.purge());  
  29.             System.out.println("Current water is " + bucketCapacity + "L");  
  30.             try {  
  31.                 Thread.sleep(2000L);  
  32.             } catch (InterruptedException e) {  
  33.                 e.printStackTrace();  
  34.             }  
  35.             timer.cancel();//取消所有  
  36.         }  
  37.     }  
  38.   
  39. }  
执行机器人
[java]  view plain  copy
  1. import java.text.SimpleDateFormat;  
  2. import java.util.Calendar;  
  3. import java.util.Timer;  
  4.   
  5. public class ExectorRobot {  
  6.   
  7.     public static void main(String[] args) {  
  8.         Timer timer = new Timer();  
  9.         //获取当前时间  
  10.         Calendar calendar = Calendar.getInstance();  
  11.         SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");  
  12.         System.out.println("Current time is" + sf.format(calendar.getTime()));  
  13.           
  14.         DancingRobot dr = new DancingRobot();  
  15.         WaterRobot wr = new WaterRobot(timer);  
  16.           
  17.         timer.schedule(dr, calendar.getTime(), 2000L);  
  18.         timer.scheduleAtFixedRate(wr, calendar.getTime(), 1000L);  
  19.     }  
  20.       
  21. }  

Timer缺陷

管理并发任务的缺陷
    Timer有且仅有一个线程去执行定时任务,如果存在多个任务,且任务时间过长,会导致执行效果与预期不符。

当任务抛出异常时缺陷
    如果TimerTask抛出RuntimeException,Timer会停止所有任务的运行。
Timer的使用禁区
    对时效性要求较高的多任务并发作业;对复杂的任务调度。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值