Java如何实现定时任务

在我们编程过程中如果需要执行一些简单的定时任务,无须做复杂的控制,我们可以考虑使用JDK中的Timer定时任务来实现。下面LZ就其原理、实例以及Timer缺陷三个方面来解析java Timer定时器。

一、简介

在java中一个完整定时任务需要由Timer、TimerTask两个类来配合完成。 API中是这样定义他们的,Timer:一种工具,线程用其安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。由TimerTask:Timer 安排为一次执行或重复执行的任务。我们可以这样理解Timer是一种定时器工具,用来在一个后台线程计划执行指定任务,而TimerTask一个抽象类,它的子类代表一个可以被Timer计划的任务。

Timer类

在工具类Timer中,提供了四个构造方法,每个构造方法都启动了计时器线程,同时Timer类可以保证多个线程可以共享单个Timer对象而无需进行外部同步,所以Timer类是线程安全的。但是由于每一个Timer对象对应的是单个后台线程,用于顺序执行所有的计时器任务,一般情况下我们的线程任务执行所消耗的时间应该非常短,但是由于特殊情况导致某个定时器任务执行的时间太长,那么他就会“独占”计时器的任务执行线程,其后的所有线程都必须等待它执行完,这就会延迟后续任务的执行,使这些任务堆积在一起,具体情况我们后面分析。

当程序初始化完成Timer后,定时任务就会按照我们设定的时间去执行,Timer提供了schedule方法,该方法有多中重载方式来适应不同的情况,如下:

schedule(TimerTask task, Date time):安排在指定的时间执行指定的任务。

schedule(TimerTask task, Date firstTime, long period) :安排指定的任务在指定的时间开始进行重复的固定延迟执行。

schedule(TimerTask task, long delay) :安排在指定延迟后执行指定的任务。

schedule(TimerTask task, long delay, long period) :安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。

同时也重载了scheduleAtFixedRate方法,scheduleAtFixedRate方法与schedule相同,只不过他们的侧重点不同,区别后面分析。

scheduleAtFixedRate(TimerTask task, Date firstTime, long period):安排指定的任务在指定的时间开始进行重复的固定速率执行。

scheduleAtFixedRate(TimerTask task, long delay, long period):安排指定的任务在指定的延迟后开始进行重复的固定速率执行。

TimerTask

TimerTask类是一个抽象类,由Timer 安排为一次执行或重复执行的任务。它有一个抽象方法run()方法,该方法用于执行相应计时器任务要执行的操作。因此每一个具体的任务类都必须继承TimerTask,然后重写run()方法。

另外它还有两个非抽象的方法:

boolean cancel():取消此计时器任务。

long scheduledExecutionTime():返回此任务最近实际执行的安排执行时间。

二、实例

 2.1、指定延迟时间执行定时任务

public class TimerTest01 {
  Timer timer;
  public TimerTest01(int time){
    timer = new Timer();
    timer.schedule(new TimerTaskTest01(), time * 1000);
  }
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {
  System.out.println(</span>"timer begin...."<span style="color: #000000">);
  </span><span style="color: #0000ff">new</span> TimerTest01(3<span style="color: #000000">);
}

}
public class TimerTaskTest01 extends TimerTask{
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
  System.out.println(</span>"Time's up!!!!"<span style="color: #000000">);
}

}

运行结果:

首先打印:timer begin....
3秒后打印:Time's up!!!!

2.2、在指定时间执行定时任务 [code]public class TimerTest02 { Timer timer;

public class TimerTest02 {
  Timer timer;
</span><span style="color: #0000ff">public</span><span style="color: #000000"> TimerTest02(){
  Date time </span>=<span style="color: #000000"> getTime();
  System.out.println(</span>"指定时间time=" +<span style="color: #000000"> time);
  timer </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> Timer();
  timer.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> TimerTaskTest02(), time);
}

</span><span style="color: #0000ff">public</span><span style="color: #000000"> Date getTime(){
  Calendar calendar </span>=<span style="color: #000000"> Calendar.getInstance();
  calendar.set(Calendar.HOUR_OF_DAY, </span>11<span style="color: #000000">);
  calendar.set(Calendar.MINUTE, </span>39<span style="color: #000000">);
  calendar.set(Calendar.SECOND, </span>00<span style="color: #000000">);
  Date time </span>=<span style="color: #000000"> calendar.getTime();

  </span><span style="color: #0000ff">return</span><span style="color: #000000"> time;
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {
  </span><span style="color: #0000ff">new</span><span style="color: #000000"> TimerTest02();
}

}
public class TimerTaskTest02 extends TimerTask{
@Override
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
  System.out.println(</span>"指定时间执行线程任务..."<span style="color: #000000">);
}

}

当时间到达11:39:00时就会执行该线程任务,当然大于该时间也会执行!!执行结果为:

指定时间time=Tue Jun 10 11:39:00 CST 2014
指定时间执行线程任务...

2.3、在延迟指定时间后以指定的间隔时间循环执行定时任务

public class TimerTest03 {
  Timer timer;
</span><span style="color: #0000ff">public</span><span style="color: #000000"> TimerTest03(){
  timer </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> Timer();
  timer.schedule(</span><span style="color: #0000ff">new</span> TimerTaskTest03(), 1000, 2000<span style="color: #000000">);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {
  </span><span style="color: #0000ff">new</span><span style="color: #000000"> TimerTest03();
}

}
public class TimerTaskTest03 extends TimerTask{
@Override
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
  Date date </span>= <span style="color: #0000ff">new</span> Date(<span style="color: #0000ff">this</span><span style="color: #000000">.scheduledExecutionTime());
  System.out.println(</span>"本次执行该线程的时间为:" +<span style="color: #000000"> date);
}

}

运行结果:

本次执行该线程的时间为:Tue Jun 10 21:19:47 CST 2014
本次执行该线程的时间为:Tue Jun 10 21:19:49 CST 2014
本次执行该线程的时间为:Tue Jun 10 21:19:51 CST 2014
本次执行该线程的时间为:Tue Jun 10 21:19:53 CST 2014
本次执行该线程的时间为:Tue Jun 10 21:19:55 CST 2014
本次执行该线程的时间为:Tue Jun 10 21:19:57 CST 2014
.................

对于这个线程任务,如果我们不将该任务停止,他会一直运行下去。

对于上面三个实例,LZ只是简单的演示了一下,同时也没有讲解scheduleAtFixedRate方法的例子,其实该方法与schedule方法一样!

2.4、分析schedule和scheduleAtFixedRate

1、schedule(TimerTask task, Date time)、schedule(TimerTask task, long delay)

对于这两个方法而言,如果指定的计划执行时间scheduledExecutionTime<= systemCurrentTime,则task会被立即执行。scheduledExecutionTime不会因为某一个task的过度执行而改变。

2、schedule(TimerTask task, Date firstTime, long period)、schedule(TimerTask task, long delay, long period)

这两个方法与上面两个就有点儿不同的,前面提过Timer的计时器任务会因为前一个任务执行时间较长而延时。在这两个方法中,每一次执行的task的计划时间会随着前一个task的实际时间而发生改变,也就是scheduledExecutionTime(n+1)=realExecutionTime(n)+periodTime。也就是说如果第n个task由于某种情况导致这次的执行时间过程,最后导致systemCurrentTime>= scheduledExecutionTime(n+1),这是第n+1个task并不会因为到时了而执行,他会等待第n个task执行完之后再执行,那么这样势必会导致n+2个的执行实现scheduledExecutionTime放生改变即scheduledExecutionTime(n+2) = realExecutionTime(n+1)+periodTime。所以这两个方法更加注重保存间隔时间的稳定。

3、scheduleAtFixedRate(TimerTask task, Date firstTime, long period)、scheduleAtFixedRate(TimerTask task, long delay, long period)

在前面也提过scheduleAtFixedRate与schedule方法的侧重点不同,schedule方法侧重保存间隔时间的稳定,而scheduleAtFixedRate方法更加侧重于保持执行频率的稳定。为什么这么说,原因如下。在schedule方法中会因为前一个任务的延迟而导致其后面的定时任务延时,而scheduleAtFixedRate方法则不会,如果第n个task执行时间过长导致systemCurrentTime>= scheduledExecutionTime(n+1),则不会做任何等待他会立即执行第n+1个task,所以scheduleAtFixedRate方法执行时间的计算方法不同于schedule,而是scheduledExecutionTime(n)=firstExecuteTime +n*periodTime,该计算方法永远保持不变。所以scheduleAtFixedRate更加侧重于保持执行频率的稳定。

三、Timer的缺陷

3.1、Timer的缺陷

Timer计时器可以定时(指定时间执行任务)、延迟(延迟5秒执行任务)、周期性地执行任务(每隔个1秒执行任务),但是,Timer存在一些缺陷。首先Timer对调度的支持是基于绝对时间的,而不是相对时间,所以它对系统时间的改变非常敏感。其次Timer线程是不会捕获异常的,如果TimerTask抛出的了未检查异常则会导致Timer线程终止,同时Timer也不会重新恢复线程的执行,他会错误的认为整个Timer线程都会取消。同时,已经被安排单尚未执行的TimerTask也不会再执行了,新的任务也不能被调度。故如果TimerTask抛出未检查的异常,Timer将会产生无法预料的行为。

1、Timer管理时间延迟缺陷

前面Timer在执行定时任务时只会创建一个线程任务,如果存在多个线程,若其中某个线程因为某种原因而导致线程任务执行时间过长,超过了两个任务的间隔时间,会发生一些缺陷:

public class TimerTest04 {
  private Timer timer;
  public long start;
</span><span style="color: #0000ff">public</span><span style="color: #000000"> TimerTest04(){
  </span><span style="color: #0000ff">this</span>.timer = <span style="color: #0000ff">new</span><span style="color: #000000"> Timer();
  start </span>=<span style="color: #000000"> System.currentTimeMillis();
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerOne(){
  timer.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> TimerTask() {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      System.out.println(</span>"timerOne invoked ,the time:" + (System.currentTimeMillis() -<span style="color: #000000"> start));
      </span><span style="color: #0000ff">try</span><span style="color: #000000"> {
        Thread.sleep(</span>4000);  <span style="color: #008000">//</span><span style="color: #008000">线程休眠3000</span>
      } <span style="color: #0000ff">catch</span><span style="color: #000000"> (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }, </span>1000<span style="color: #000000">);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerTwo(){
  timer.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> TimerTask() {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      System.out.println(</span>"timerOne invoked ,the time:" + (System.currentTimeMillis() -<span style="color: #000000"> start));
    }
  }, </span>3000<span style="color: #000000">);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> main(String[] args) <span style="color: #0000ff">throws</span><span style="color: #000000"> Exception {
  TimerTest04 test </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> TimerTest04();

  test.timerOne();
  test.timerTwo();
}

}

按照我们正常思路,timerTwo应该是在3s后执行,其结果应该是:

timerOne invoked ,the time:1001
timerOne invoked ,the time:3001

但是事与愿违,timerOne由于sleep(4000),休眠了4S,同时Timer内部是一个线程,导致timeOne所需的时间超过了间隔时间,结果:

timerOne invoked ,the time:1000
timerOne invoked ,the time:5000

2、Timer抛出异常缺陷

如果TimerTask抛出RuntimeException,Timer会终止所有任务的运行。如下:

public class TimerTest04 {
  private Timer timer;
</span><span style="color: #0000ff">public</span><span style="color: #000000"> TimerTest04(){
  </span><span style="color: #0000ff">this</span>.timer = <span style="color: #0000ff">new</span><span style="color: #000000"> Timer();
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerOne(){
  timer.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> TimerTask() {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span><span style="color: #000000"> RuntimeException();
    }
  }, </span>1000<span style="color: #000000">);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerTwo(){
  timer.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> TimerTask() {

    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      System.out.println(</span>"我会不会执行呢??"<span style="color: #000000">);
    }
  }, </span>1000<span style="color: #000000">);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {
  TimerTest04 test </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> TimerTest04();
  test.timerOne();
  test.timerTwo();
}

}

运行结果:timerOne抛出异常,导致timerTwo任务终止。

Exception in thread "Timer-0" java.lang.RuntimeException
    at com.chenssy.timer.TimerTest04$1.run(TimerTest04.java:25)
    at java.util.TimerThread.mainLoop(Timer.java:555)
    at java.util.TimerThread.run(Timer.java:505)

对于Timer的缺陷,我们可以考虑 ScheduledThreadPoolExecutor 来替代。Timer是基于绝对时间的,对系统时间比较敏感,而ScheduledThreadPoolExecutor 则是基于相对时间;Timer是内部是单一线程,而ScheduledThreadPoolExecutor内部是个线程池,所以可以支持多个任务并发执行。

3.2、用ScheduledExecutorService替代Timer

1、解决问题一:

public class ScheduledExecutorTest {
  private ScheduledExecutorService scheduExec;
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">long</span><span style="color: #000000"> start;

ScheduledExecutorTest(){
  </span><span style="color: #0000ff">this</span>.scheduExec = Executors.newScheduledThreadPool(2<span style="color: #000000">);
  </span><span style="color: #0000ff">this</span>.start =<span style="color: #000000"> System.currentTimeMillis();
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerOne(){
  scheduExec.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> Runnable() {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      System.out.println(</span>"timerOne,the time:" + (System.currentTimeMillis() -<span style="color: #000000"> start));
      </span><span style="color: #0000ff">try</span><span style="color: #000000"> {
        Thread.sleep(</span>4000<span style="color: #000000">);
      } </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (InterruptedException e) {
        e.printStackTrace();
      }
    }
  },</span>1000<span style="color: #000000">,TimeUnit.MILLISECONDS);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerTwo(){
  scheduExec.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> Runnable() {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      System.out.println(</span>"timerTwo,the time:" + (System.currentTimeMillis() -<span style="color: #000000"> start));
    }
  },</span>2000<span style="color: #000000">,TimeUnit.MILLISECONDS);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {
  ScheduledExecutorTest test </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> ScheduledExecutorTest();
  test.timerOne();
  test.timerTwo();
}

}

运行结果:

timerOne,the time:1003
timerTwo,the time:2005

2、解决问题二

public class ScheduledExecutorTest {
  private ScheduledExecutorService scheduExec;
</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">long</span><span style="color: #000000"> start;

ScheduledExecutorTest(){
  </span><span style="color: #0000ff">this</span>.scheduExec = Executors.newScheduledThreadPool(2<span style="color: #000000">);
  </span><span style="color: #0000ff">this</span>.start =<span style="color: #000000"> System.currentTimeMillis();
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerOne(){
  scheduExec.schedule(</span><span style="color: #0000ff">new</span><span style="color: #000000"> Runnable() {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      </span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span><span style="color: #000000"> RuntimeException();
    }
  },</span>1000<span style="color: #000000">,TimeUnit.MILLISECONDS);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> timerTwo(){
  scheduExec.scheduleAtFixedRate(</span><span style="color: #0000ff">new</span><span style="color: #000000"> Runnable() {
    </span><span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span><span style="color: #000000"> run() {
      System.out.println(</span>"timerTwo invoked ....."<span style="color: #000000">);
    }
  },</span>2000,500<span style="color: #000000">,TimeUnit.MILLISECONDS);
}

</span><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span><span style="color: #000000"> main(String[] args) {
  ScheduledExecutorTest test </span>= <span style="color: #0000ff">new</span><span style="color: #000000"> ScheduledExecutorTest();
  test.timerOne();
  test.timerTwo();
}

}

运行结果:

timerTwo invoked .....
timerTwo invoked .....
timerTwo invoked .....
timerTwo invoked .....
timerTwo invoked .....
timerTwo invoked .....
timerTwo invoked .....
timerTwo invoked .....
timerTwo invoked .....
........................

到此这篇关于Java如何实现定时任务的文章就介绍到这了,更多相关Java定时任务内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2020-07-30

Java定时任务详解

定时任务在项目中经常会使用到,本文主要根据博主自己使用定时的经验分如下几点介绍定时任务: 1.Quartz定时任务简介及Spring配置Quartz定时任务 2.SchedulerFactory对定时任务进行增删改查 3.总结 Quartz定时任务简介: Quartz是项目中经常用到的定时任务之一,是一个完全由java编写的开源作业调度框架,可以与J2EE与J2SE应用程序相结合也可以单独使用,其主要组成部分包括Job.Scheduler.CronExpression,这里就不一一介绍了,下面介

Java循环调用多个timer实现定时任务

通常在使用java实现定时任务时,有两种方法,一种是spring中的schedule(cron = " */5 * * * ?"),另一种就是java中的timer, timer+TimerTask配合实现,这里附上Timer对象的一些常用api Timer() 创建-个新计时器. Timer(boolean isDaemon) 创建一个新计时器, 可以指定其相关的线程作为守护程序运行. Timer(String, name) 创建一个新计时器,其相关的线程具有指定的名称. Timer

java定时任务Timer和TimerTask使用详解

timer和timertask是jdk自带的定时任务实现,无需导入第三方jar包来完成 1.指定多久之后执行此任务,注意:只会执行一次 public class TimerTest { Timer timer; public TimerTest(int time){ timer = new Timer(); timer.schedule(new timerTaskTest(),time*1000);//timer.schedule(执行的方法,延迟多久执行(ms)) } public stati

java 中Spring task定时任务的深入理解

java 中Spring task定时任务的深入理解 在工作中有用到spring task作为定时任务的处理,spring通过接口TaskExecutor和TaskScheduler这两个接口的方式为异步定时任务提供了一种抽象.这就意味着spring容许你使用其他的定时任务框架,当然spring自身也提供了一种定时任务的实现:spring task.spring task支持线程池,可以高效处理许多不同的定时任务.同时,spring还支持使用Java自带的Timer定时器和Quartz定时框架.

在Java Web项目中添加定时任务的方法

在Java Web程序中加入定时任务,这里介绍两种方式:1.使用监听器注入:2.使用Spring注解@Scheduled注入. 推荐使用第二种形式. 一.使用监听器注入 ①:创建监听器类: import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; public class TimerDataTaskListener implements ServletContextListener

java 动态增加定时任务示例

整理文档,java 动态增加定时任务示例,直接上代码. import org.apache.tools.ant.util.DateUtils; import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerFactory; import org.quartz.impl.StdSchedulerFactory; import ja

Java下SpringBoot创建定时任务详解

序言 使用SpringBoot创建定时任务非常简单,目前主要有以下三种创建方式: 一.基于注解(@Scheduled) 二.基于接口(SchedulingConfigurer) 前者相信大家都很熟悉,但是实际使用中我们往往想从数据库中读取指定时间来动态执行定时任务,这时候基于接口的定时任务就派上用场了. 三.基于注解设定多线程定时任务 一.静态:基于注解 基于注解@Scheduled默认为单线程,开启多个任务时,任务的执行时机会受上一个任务执行时间的影响. 1.创建定时器 使用SpringBoo

Java定时任务的三种实现方式

前言 现代的应用程序早已不是以前的那些由简单的增删改查拼凑而成的程序了,高复杂性早已是标配,而任务的定时调度与执行也是对程序的基本要求了. 很多业务需求的实现都离不开定时任务,例如,每月一号,移动将清空你上月未用完流量,重置套餐流量,以及备忘录提醒.闹钟等功能. Java 系统中主要有三种方式来实现定时任务: Timer和TimerTask ScheduledExecutorService 三方框架 Quartz 下面我们一个个来看. Timer和TimerTask 先看一个小 demo,接着我

Java Web项目中编写定时任务的实现

之前在的公司有专门的任务调度框架,需要使用的时候引个jar包加个配置和注解就可以使用了,还有专门的平台来维护运行的机器及监控执行状态等等. 现在突然没了这个工具,而又要写定时任务,该怎么办呢? 对于非Web应用来说,我们可以使用Quartz,使用简单,功能强大. 对于Java Web应用来说,当然也可以使用Quartz(有一篇介绍了方法:http://www.jb51.net/article/104105.htm),但是还有更方便的工具,那就是spring自带的支持定时任务功能. Spring的

Java实现终止线程池中正在运行的定时任务

最近项目中遇到了一个新的需求,就是实现一个可以动态添加定时任务的功能.说到这里,有人可能会说简单啊,使用quartz就好了,简单粗暴.然而quartz框架太重了,小项目根本不好操作啊.当然,也有人会说,jdk提供了timer的接口啊,完全够用啊.但是我们项目的需求完全是多线程的模型啊,而timer是单线程的,so,楼主最后还是选择了jdk的线程池. 线程池是什么 Java通过Executors提供四种线程池,分别为: newCachedThreadPool :创建一个可缓存线程池,如果线程池长度

Java手写线程池的实现方法

本文实例为大家分享了Java手写线程池的实现代码,供大家参考,具体内容如下 1.线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务.线程池线程都是后台线程. 2.线程池简易架构 3.简易线程池代码(自行优化) import java.util.List; /** * 线程接口 * * @Author yjian * @Date 14:49 2017/10/14 **/ public interface IThreadPool { //加入任务 void ex

详谈Java几种线程池类型介绍及使用方法

一.线程池使用场景 •单个任务处理时间短 •将需处理的任务数量大 二.使用Java线程池好处 1.使用new Thread()创建线程的弊端: •每次通过new Thread()创建对象性能不佳. •线程缺乏统一管理,可能无限制新建线程,相互之间竞争,及可能占用过多系统资源导致死机或oom. •缺乏更多功能,如定时执行.定期执行.线程中断. 2.使用Java线程池的好处: •重用存在的线程,减少对象创建.消亡的开销,提升性能. •可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞

Java并发之线程池Executor框架的深入理解

线程池 无限制的创建线程 若采用"为每个任务分配一个线程"的方式会存在一些缺陷,尤其是当需要创建大量线程时: 线程生命周期的开销非常高 资源消耗 稳定性 引入线程池 任务是一组逻辑工作单元,线程则是使任务异步执行的机制.当存在大量并发任务时,创建.销毁线程需要很大的开销,运用线程池可以大大减小开销. Executor框架 说明: Executor 执行器接口,该接口定义执行Runnable任务的方式. ExecutorService 该接口定义提供对Executor的服务. Sched

java基于线程池和反射机制实现定时任务完整实例

本文实例讲述了java基于线程池和反射机制实现定时任务的方法.分享给大家供大家参考,具体如下: 主要包括如下实现类: 1. Main类: 任务执行的入口: 调用main方法,开始加载任务配置并执行任务 package com.yanek.task; import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import ja

C#线程处理系列之线程池中的I/O线程

一.I/O线程实现对文件的异步  1.1  I/O线程介绍: 对于线程所执行的任务来说,可以把线程分为两种类型:工作者线程和I/O线程. 工作者线程用来完成一些计算的任务,在任务执行的过程中,需要CPU不间断地处理,所以,在工作者线程的执行过程中,CPU和线程的资源是充分利用的. I/O线程主要用来完成输入和输出的工作的,在这种情况下, 计算机需要I/O设备完成输入和输出的任务,在处理过程中,CPU是不需要参与处理过程的,此时正在运行的线程将处于等待状态,只有等任务完成后才会有事可做, 这样就造

线程池中使用spring aop事务增强

这篇文章主要介绍了线程池中使用spring aop事务增强,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 问题描述: 在项目里使用了线程池运行同一个类的实例方法,代码大致如下,运行时发现job方法的事务不生效 @Transactional public void doJob() { EXECOTOR.execute(() ->job()); } @Transactional public void job(){ //db operation }

Java四种线程池的使用详解

Java通过Executors提供四种线程池,分别为: newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待. newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行. newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,

java简单实现多线程及线程池实例详解

本文为大家分享了java多线程的简单实现及线程池实例,供大家参考,具体内容如下 一.多线程的两种实现方式 1.继承Thread类的多线程 /** * 继承Thread类的多线程简单实现 */ public class extThread extends Thread { public void run(){ for(int i=0;i<100;i++){ System.out.println(getName()+"-"+i); } } public static void mai

Java线程池FutureTask实现原理详解

前言 线程池可以并发执行多个任务,有些时候,我们可能想要跟踪任务的执行结果,甚至在一定时间内,如果任务没有执行完成,我们可能还想要取消任务的执行,为了支持这一特性,ThreadPoolExecutor提供了 FutureTask 用于追踪任务的执行和取消.本篇介绍FutureTask的实现原理. 类视图 为了更好的理解FutureTask的实现原理,这里先提供几个重要接口和类的结构,如下图所示: RunnableAdapter ThreadPoolExecutor提供了submit接口用于提交任