在jdk1.5里面已经为我们添加了线程池这个特性,因此我们在使用过程中还是比较方便的。
通过工具类java.util.concurrent.Executors可以轻松的创建线程池,通过查看源码,发现创建线程池的方法比较多,可以创建固定大小,带缓存和定时任务。这里主要看下固定大小和定时任务的线程池
1.固定大小线程池:
首先创建3个线程池,通过工具类Executors来完成,具体如下
ExecutorService threadPools = Executors.newFixedThreadPool(3);
这样就创建了线程池,这里为了简单操作,采用execute来执行线程操作而不是通过submit,当然submit提交后返回Future能更方便的了解线程执行的结果
package com.jacksoft.thread; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * 线程池 * @author Jack * */ public class ThreadPoolTest { public static void main(String[] args) { ExecutorService threadPools = Executors.newFixedThreadPool(3); for(int i = 0; i < 3; i++){ threadPools.execute(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "运行"); } }); } threadPools.shutdown(); } }
首先我们创建的是3个大小的线程池,然后再通过循环,分别执行execute方法来实现线程运行
2.定时任务线程
有时候我们需要创建一个线程,但是不是立刻就执行或者说规定的什么时候才去执行,这时就需要一个定时线程来完成,对应线程池同样采用Executors工具来创建
ScheduledExecutorService threadPools = Executors.newScheduledThreadPool(2);
返回java.util.concurrent.ScheduledExecutorService的实现,该接口继承ExecutorService,所以还是可以通过execute方法来执行线程,但是这样就不能实现定时的作用。这里需要调用schedule方法来完成调度,跟定时器实现一样,查看ScheduledExecutorService.schedule方法
/** * Creates and executes a one-shot action that becomes enabled * after the given delay. * * @param command the task to execute * @param delay the time from now to delay execution * @param unit the time unit of the delay parameter * @return a ScheduledFuture representing pending completion of * the task and whose <tt>get()</tt> method will return * <tt>null</tt> upon completion * @throws RejectedExecutionException if the task cannot be * scheduled for execution * @throws NullPointerException if command is null */ public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit);
需要传递3个参数,第一个Runnable实现,这个很熟悉了,delay是从现在开始多久执行,unit是delay的时间单位,可以通过TimeUnit来获取
下面就写个简单的运行后2秒再开始执行线程
package com.jacksoft.thread; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 线程池 * @author Jack * */ public class ThreadPoolTest { public static void main(String[] args) { ScheduledExecutorService threadPools = Executors.newScheduledThreadPool(2); for(int i = 0; i < 2;i++){ threadPools.schedule(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "定时器执行"); } }, 2, TimeUnit.SECONDS); } threadPools.shutdown(); } }
这样再2秒之后,才会执行线程。
和定时器一样,也可以一直运行,可以分别通过scheduleWithFixedDelay和scheduleAtFixedRate方法来完成调度,我们先采用scheduleWithFixedDelay方法来完成
package com.jacksoft.thread; import java.util.Calendar; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 线程池 * @author Jack * */ public class ThreadPoolTest { public static void main(String[] args) { ScheduledExecutorService threadPools = Executors.newScheduledThreadPool(2); for(int i = 0; i < 2;i++){ threadPools.scheduleWithFixedDelay(new Runnable() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "运行" + new Date().getSeconds()); } },0, 4, TimeUnit.SECONDS); } } }
这里采用sleep来模拟业务处理过程,让该线程睡眠5秒,程序运行的结果如下:
pool-1-thread-2运行53 pool-1-thread-1运行53 pool-1-thread-1运行2 pool-1-thread-2运行2 pool-1-thread-1运行11 pool-1-thread-2运行11 pool-1-thread-1运行20 pool-1-thread-2运行20
再来通过scheduleAtFixedRate来完成调度,同样的打印执行结果,代码如下:
package com.jacksoft.thread; import java.util.Calendar; import java.util.Date; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 线程池 * * @author Jack * */ public class ThreadPoolTest { public static void main(String[] args) { ScheduledExecutorService threadPools = Executors .newScheduledThreadPool(2); for (int i = 0; i < 2; i++) { threadPools.scheduleAtFixedRate(new Runnable() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "运行" + new Date().getSeconds()); } }, 0, 4, TimeUnit.SECONDS); } } }
执行结果:
pool-1-thread-2运行29 pool-1-thread-1运行29 pool-1-thread-1运行34 pool-1-thread-2运行34 pool-1-thread-1运行39 pool-1-thread-2运行39 pool-1-thread-1运行44 pool-1-thread-2运行44
通过上面两个方法都可以实现定时调度我们的任务,但是通过打印结果来看,还是存在区别的
scheduleAtFixedRate 这个方法是不管你有没有执行完,反正我每隔4秒来执行一次,以相同的频率来执行
scheduleWithFixedDelay 这个是等你方法执行完后,我再隔4秒来执行,也就是相对延迟后,以固定的频率去执行
举个列子:
1. 当我们去坐火车时,火车都准点发车,当然在这种情况很少,除非始发站。那么火车是不会等你的,到点了他就运行,然后隔一天,同样的车次在同样的时间又开始运行,他不管前一天的火车是不是已经到达终点,这就是scheduleAtFixedRate 调度
2. 日常生活中一日三餐,早饭吃完了,休息或者上班到中午,再吃午饭,然后又是上班到晚上再吃晚饭,不能早饭一直吃到中午,然后马上又吃午饭吧,等一件事件做完了,然后相对间隔多久,再去做这件事情,这就是scheduleWithFixedDelay 调度,可能这个例子不是很好。。。
相关推荐
java 线程池 完整 源码 java 线程池 完整 源码
主要给大家介绍了关于java线程池使用后到底要不要关闭的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Reference: 《创建Java线程池》[1],《Java线程:新特征-线程池》[2], 《Java线程池学习》[3],《线程池ThreadPoolExecutor使用简介》[4],《Java5中的线程池实例讲解》[5],《ThreadPoolExecutor使用和思考》[6] ...
Java线程池使用说明Java线程池使用说明Java线程池使用说明
java线程池知识、
java线程池封装j
简单的线程池程序+中文文档 包结构: com.tangkai.threadpool --SimpleThread.java 工作线程 --TestThreadPool.java 程序入口 --ThreadPoolManager.java 线程池管理类
2.然后根据提示运行java命令执行示例程序,观看线程池的运行结果 目标:Java中多线程技术是一个难点,但是也是一个核心技术。因为Java本身就是一个多线程语言。本人目前在给46班讲授Swing的网络编程--使用Swing来...
基于Java线程池技术实现Knock Knock游戏项目.zip 基于Java线程池技术实现Knock Knock游戏项目.zip 基于Java线程池技术实现Knock Knock游戏项目.zip 基于Java线程池技术实现Knock Knock游戏项目.zip 基于Java线程池...
Java线程池及观察者模式解决多线程意外死亡重启问题,附件含两个要运行代码!
讲述了java线程池的优点,参数,6种线程池的使用场景,线程池用到的handler,线程任务的提交方式等等。
java线程池实例java线程池实例E:\Users\Administrator\workspace
自定义实现Java线程池,学习大师设计思想,瞻仰大神笔法
java线程池的源码分析以及各种池之间的对比;
基于Java线程池技术的数据爬虫设计与实现.pdf
JAVA线程池的原理与实现.pdf
java技术学习——基于Java线程池技术实现Knock Knock游戏项目(包含服务端、客户端两部分) java技术学习——基于Java线程池技术实现Knock Knock游戏项目(包含服务端、客户端两部分) java技术学习——基于Java...
1.媲美java线程池框架,整套源码资源,使用Intellij Idea开发工具,JDK1.8以上 2.带有测试代码 3.可以根据项目实际情况任意调整代码 4.任务队列、拒绝策略 5.BasicThreadPool.java、LinkedRunnableQueue.java、...
java线程池的原理和实现,挺全面的,分享给大家!