- 浏览: 128230 次
- 来自: 杭州
文章分类
最新评论
-
worldcbf:
ximinjie 写道advantech 写道截个生日还用正则 ...
身份证号码正则截取生日golang和java实现 -
tuyong520:
...
spring mvc+shiro +cas +spring-session 的通用权限管理系统 -
ximinjie:
advantech 写道截个生日还用正则表达式?我也是醉了。不 ...
身份证号码正则截取生日golang和java实现 -
kingcs2008:
无表结构啊!!!!
springsecurity3.1.3 案例源码 -
advantech:
截个生日还用正则表达式?我也是醉了。不管一代证还是二代证,从第 ...
身份证号码正则截取生日golang和java实现
JAVA语言中引入了线程(Thread)的概念,这让程序员极大方便的操作线程,但是也带来了很多的弊端,如数据共享、同步、死锁等问题。java虚拟机支持多个线程在应用程序上并发运行,这样大大的增加了处理器的吞吐量,不过线程的创建、调度、销毁等非常耗时而又耗内存的缺点,由此引入了线程池的概念。那什么是线程池呢?比如就是打个比方,每年九月份最忙最热闹的是大学校园,新生报道,对就是新生报道。我们把新生报道看成一个任务,每个任务在没有引入线程池的时候,会为每个任务创建一个线程,当任务完成的时候会把当前执行任务的线程销毁,你想想在现实的生活中,登记报道的工作人员也就是那几个人,那样工作人员不累死才怪,有了线程池的概念,会把对应的任务交个线程池,然后线程池会把任务分发到指定的空闲的线程进行执行任务,当任务执行完成后,不会销毁线程,而是要归还给线程池;如果当把任务提交给线程池的时候,这时恰当没有空闲的线程来执行此提交的任务,线程池会把这个提交的任务放在任务队列中,直到有空闲的线程来分发。线程池的引入大大的减少了线程的创建与销毁的开销。
下面我们来看下是如果在JAVA5中如何创建线程池
1、创建单一线程的线程池
package mail; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * @author dongtian * @date 2015年6月12日 下午2:52:32 */ public class ThreadPool { public static void main(String[] args) throws Exception { //创建单一线程的线程池 ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor(); //将任务提交给线程(线程池会将任务分发给指定的空闲线程执行具体任务) newSingleThreadExecutor.execute(new Runnable() { public void run() { try { Thread.sleep(5000); System.err.println("我是单个线程的线程池中的一个线程" + Thread.currentThread().getName()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); /** * 注销线程池 此方法会等待线程正在执行任务完成 * 而对应的@shutdownNow()则不会等待此时线程执行的任务结束 **/ newSingleThreadExecutor.shutdown(); } }
2、创建线程数量固定大小的线程池
package mail; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * * @author dongtian * @date 2015年6月12日 下午3:01:59 */ public class FixedThreadPoolTest { public static void main(String[] args) { ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5); newFixedThreadPool.execute(new Runnable() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.err.println("我是fixedpool中线程 "+ Thread.currentThread().getName()); } }); newFixedThreadPool.shutdown(); } }
3、创建可缓存的线程池
这个线程池比较有意思 初始化的时候是没有一个线程
没到将任务放在此线程,它就查看当前线程池中是否有空闲的线程,如果没有会创建一个线程放入此线程池
然后执行任务,任务执行完成之后会 将刚才创建的线程放入线程池中。但是这个线程池不是常在的, 它会检查线程池中线程如果在60秒钟没有使用的话,会将此线程从缓存中删除
这个线程池比较有意思 初始化的时候是没有一个线程
没到将任务放在此线程,它就查看当前线程池中是否有空闲的线程,如果没有会创建一个线程放入此线程池
然后执行任务,任务执行完成之后会 将刚才创建的线程放入线程池中。但是这个线程池不是常在的, 它会检查线程池中线程如果在60秒钟没有使用的话,会将此线程从缓存中删除
具体代码如下:
package mail; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /*** * 可缓存的线程池 * * @author dongtian * @date 2015年6月12日 下午3:04:57 */ public class CachedThreadPoolTest { public static void main(String[] args) { /** * 创建一个可缓存的线程池 * 这个线程池比较有意思 初始化的时候是没有一个线程 * 没到将任务放在此线程,它就查看当前线程池中是否有空闲的线程,如果没有会创建一个线程放入此线程池 * 然后执行任务,任务执行完成之后会 将刚才创建的线程放入线程池中。但是这个线程池不是常在的,它会检查 * 线程池中线程如果在60秒钟没有使用的话,会将此线程从缓存中删除 * */ ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); newCachedThreadPool.execute(new Runnable() { @Override public void run() { } }); newCachedThreadPool.shutdown(); } }4、可任务时间调度的线程池
package mail; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; /** * 可定时调度任务的线程池 * @author dongtian * @date 2015年6月12日 下午3:13:02 */ public class ScheduledThreadPoolTest { public static void main(String[] args) { /*** * 创建可任务调度的线程池 */ ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(5); /*** * 参数说明 * 1:Runnable 具体工作任务 * 2:delay 延时事件 * 3:timeUnit 就是 前面的那个delay数字代表是年 月日 等时间单位 * */ newScheduledThreadPool.schedule(new Runnable() { @Override public void run() { System.err.println("我在调用5秒后执行...."); } }, 5, TimeUnit.SECONDS); newScheduledThreadPool.shutdown(); } }二、像线程池中提交任务
把具体要执行的任务提交给线程池,让线程池自己来分发任务有两种方式提交任务,
1、无返回值的提交任务
service.execute(Runnable able);
通过调用 service的 execute方法来提交任务到线程池,是没有返回值的,
如下通过execute方法提交任务到线程池 将没有返回值
newFixedThreadPool.execute(new Runnable() { @Override public void run() { try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.err.println("我是fixedpool中线程 "+ Thread.currentThread().getName()); } });
2、有返回值的提交任务到线程池(获取反馈信息)
在实际的任务中我们想从任务执行完毕会有个指定的返回值,我们拿来结果来进行分析(如: 批量返送邮件,如果一次性发送100000封 我们要知道有多少发送成功,有多少发送失败)这就用到了带返回值。提交任务 方式为submit 任务接口必须是 Callable<V>具体代码如下:
package mail; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /*** * 带有返回值的提交任务到线程池 * @author dongtian * @date 2015年6月12日 下午3:32:08 */ public class CallableTest { public static void main(String[] args) throws Exception { ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(5); //带有返回值的提交任务到线程池 Future<String> future = newFixedThreadPool.submit(new Callable<String>() { public String call() throws Exception { Thread.sleep(4000); return "冬天"; } }); //打印结果 System.err.println(future.get()); newFixedThreadPool.shutdown(); } }
三、线程池的等待
在线程池中有个方法awaitTermination(delay,timeunit)等待多长时间,比如我们可以每秒查询当前线程池是否注销完成所有任务具体代码如下:
package mail; import java.util.concurrent.Callable; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /*** * waitfor * @author dongtian * @date 2015年6月12日 下午5:12:39 */ public class WaitTask { public static void main(String[] args) { ThreadPoolExecutor executor = new ThreadPoolExecutor(30, 30, 1, TimeUnit.SECONDS, new LinkedBlockingQueue()); executor.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(5000); return null; } }); executor.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(2000); return null; } }); executor.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(100); return null; } }); executor.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(100); return null; } }); executor.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(100); return null; } }); executor.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(100); return null; } }); executor.submit(new Callable<String>() { @Override public String call() throws Exception { Thread.sleep(200000); return null; } }); executor.shutdown(); while (!executor.isTerminated()) { try { executor.awaitTermination(1, TimeUnit.SECONDS); System.err.println("阴湿傻吊赶快喊自己是傻吊,阴湿喊了" + executor.getCompletedTaskCount() +"次"); if(executor.getCompletedTaskCount() >=6) { System.err.println("喊够了..阴湿脱衣服了......"); } } catch (InterruptedException e) { e.printStackTrace(); } } } }四、实战
我们将模拟一个批量发送邮件的案例,来统计并行任务反馈信息,来统计发送成功多少封邮箱和发送失败多少封邮件,我们这里不用Executors的静态方法,我们采用 ThreadPoolExecutor类来创建一个线程池,构造方法初始化线程数 最大线程数,超出初始化的线程数的线程 执行完成任务存留时长,任务队列
1、模拟发送邮件
SendEmail 实现Callable接口 来模拟发送邮件的功能
package mail; import java.util.concurrent.Callable; public class SendEmailTask implements Callable<Boolean> { @Override public Boolean call() throws Exception { //模拟发送邮件 Thread.sleep(200); if(Math.random() *0.5 > 0.2) { return false; } return true; } }2、测试类
测试类用来模拟发送10000封邮件
package mail; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; /*** * 模拟发送邮件测试类 * @author dongtian * @date 2015年6月12日 下午5:24:06 */ public class SendEmailTest { public static void main(String[] args) throws Exception { ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(30, 30, 1, TimeUnit.SECONDS, new LinkedBlockingQueue()); List<Future<Boolean>> futures = new ArrayList<Future<Boolean>>(1000); for (int i = 0; i < 1000; i++) { futures.add(poolExecutor.submit(new SendEmailTask())); } System.err.println("shutdown ....."); poolExecutor.shutdown(); while (!poolExecutor.isTerminated()) { poolExecutor.awaitTermination(1, TimeUnit.SECONDS); System.err.println("已经完成 " + poolExecutor.getCompletedTaskCount()); } int error = 0; int success = 0; for (Future<Boolean> future : futures) { if (future.get() == true) { success ++; } else { error ++; } } System.err.println("已经成功发送了 " + success +"封邮件 发送失败 " +error +"封"); } }
发表评论
-
hadoop2.9全分布式安装
2018-09-10 20:41 2756一.环境说明 安装介质 :virtualbox ce ... -
raft算法一些问题疑惑
2017-11-20 10:05 0raft 算法与 paxos 算法一样都是为了解决分布 ... -
Java中ReentrantLock的lock和unlock过程
2017-11-13 16:40 1947NonfairSync锁是重入锁的一种非公平锁,是指 ... -
Spi扩展加载机制
2017-10-31 23:26 1213一、概述 我们都知道 Java的S ... -
Java内存区域总结
2017-03-26 16:44 1043Java内存区域总结 一 ... -
java NIO套接字编程
2016-10-12 17:06 1009java NIO套接字编程 在java的套接 ... -
身份证号码正则截取生日golang和java实现
2016-06-20 11:08 5333身份证号码正则截取生日golang和java实现 身份证分 ... -
springmvc全注解配置
2016-04-19 19:30 2167springmvc全注解配置 <!DOCTYPE w ... -
spring mvc+shiro +cas +spring-session 的通用权限管理系统
2015-12-18 15:24 15233spring mvc+shiro +cas +spr ... -
JVM中内存溢出OutOfMemoryError
2015-12-15 10:08 0在Java虚拟机的运行时数据区的内存中,出 ... -
Java多线程-并发容器
2015-11-30 14:34 1333Java多线程-并发容器 ... -
Java的 class文件结构
2015-11-24 11:51 1104Java-class文件结构 一、概述 ... -
thrift 的简单实用案例
2015-11-23 16:08 4828thrift 的简单实用案例 thr ... -
Java多线程-自己动手写个线程池
2015-11-19 13:39 1809package pool; public inter ... -
SpringMVC 日期参数转换报错问题最终解决方案
2015-10-19 10:15 11931在用Springmvc的日期类型作为参数的时候,会碰到 ... -
java多线程之读写锁
2015-07-26 18:04 0Java多线程之读写锁 在我们是实际生活中我们 ... -
java多线程之生产者与消费者模型2
2015-07-25 14:10 687java多线程之生产者与消费者模型2 在java5中加入 ... -
java多线程之-生产者与消费者
2015-07-24 17:19 2239java多线程之-并发协作【生产者与消费者】模型 对于多 ... -
5、Java5多线程---同步辅助工具类CyclicBarrier
2015-06-16 16:13 682Java5多线程---同步辅助工具类CyclicBarri ... -
4、Java5多线程---信号量(Semaphore)的使用
2015-06-16 14:22 1984Java5多线程---信号量(Semaphore)的使用 ...
相关推荐
在多线程大师Doug Lea的贡献下,在JDK1.5中加入了许多对并发特性的支持,例如:线程池。.......................................JAVA线程、线程池资料----下载不扣分,回帖加1分,欢迎下载,童叟无欺JAVA线程、...
Java 多线程-Socket 编程 Java 多线程-Socket 编程是指在 Java 语言中使用多线程技术来实现网络编程,特别是使用 Socket 编程来实现客户端和服务器端的通信。在 Java 中,多线程可以使用 Thread 类和 Runnable 接口...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了程序的效率和响应速度。在Java中,我们可以通过实现Runnable接口或继承Thread类来创建线程。然而,直接使用线程可能存在一些问题,如资源管理...
线程的状态管理是多线程编程中非常重要的部分。Java线程有六种状态:NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED。NEW表示线程刚创建还未启动,RUNNABLE表示线程在执行或等待CPU资源,BLOCKED表示...
在Java编程中,多线程是并发编程的重要组成部分,它允许程序同时执行多个任务,从而提高了系统的效率和响应性。然而,在某些场景下,我们可能需要控制线程的执行顺序,确保它们按照特定的顺序交替运行,这在并发编程...
在Java多线程编程中,有时我们需要确保所有子线程执行完毕后再进行后续操作,例如在并发测试、数据聚合或资源清理等场景。本篇文章将详细介绍五种在Java中等待所有子线程执行完的方法。 ### 方法一:使用`sleep`...
Java多线程学习是编程领域中的重要一环,特别是在服务器端和网络编程中,多线程技术能够有效地利用系统资源,提高程序的并发性。FTP(File Transfer Protocol)上传则是通过网络将本地文件传输到远程服务器的过程。...
综上所述,"java多线程查询数据库"是一个涉及多线程技术、线程池管理、并发控制、分页查询等多个方面的复杂问题。通过理解和掌握这些知识点,我们可以有效地提高数据库操作的效率和系统的响应速度。
Java线程:新特征-线程池 Java线程:新特征-有返回值的线程 Java线程:新特征-锁(上) Java线程:新特征-锁(下) Java线程:新特征-信号量 Java线程:新特征-阻塞队列 Java线程:新特征-阻塞栈 Java线程:新特征-...
Java并发编程实践中的线程池是一个关键的概念,它在多线程编程中扮演着至关重要的角色,有效地管理和调度线程资源,以提高系统的性能和效率。线程池通过复用已存在的线程来减少线程的创建和销毁开销,避免了频繁的上...
除了`ThreadPoolExecutor`,Java还提供了`Executors`工具类,它提供了一些预设的线程池配置,如`newFixedThreadPool`(固定大小线程池)、`newSingleThreadExecutor`(单线程线程池)等,方便开发者快速创建线程池。...
### Java多线程分页查询知识点详解 #### 一、背景与需求分析 在实际的软件开发过程中,尤其是在处理大量数据时,如何高效地进行数据查询成为了一个关键问题。例如,在一个用户众多的社交平台上,当用户需要查看...
Java多线程编程,生命游戏,用线程池.zipJava多线程编程,生命游戏,用线程池.zip Java多线程编程,生命游戏,用线程池.zipJava多线程编程,生命游戏,用线程池.zip Java多线程编程,生命游戏,用线程池.zipJava多...
Java多线程实现数据切割批量执行,实现限流操作。 java线程池Executors实现数据批量操作。 批量异步Executors处理数据,实现限流操作,QPS限流。 线程池调用第三方接口限流实现逻辑。 案例适合: 1.批量处理大数据。...
线程池管理和多线程上传是并发编程中的一个重要实践,特别是在大数据传输和网络服务中。在Java等编程语言中,线程池通过有效地管理和复用线程资源,避免了频繁创建和销毁线程带来的开销,提升了系统性能。下面将详细...
在“WHUT-java多线程实验-第三周-文件上传和下载.zip”这个实验中,我们将重点探讨如何在多线程环境中实现文件的上传和下载功能。这个实验基于IntelliJ IDEA开发环境,它是一个流行的Java集成开发环境,提供了丰富的...
在Java编程中,线程池是一种高效管理线程资源的方式,可以提高系统的性能和响应速度。本篇将探讨如何模拟Java的JDK线程池执行流程,以理解其设计原理。核心知识点包括线程池的执行策略、接口设计以及异常处理。 ...
因为线程池中仍然有很多线程在运行,占用系统资源,导致内存泄露和应用崩溃。 通过实例代码,我们可以看到,如果不关闭线程池,可能会导致内存泄露和应用崩溃。在代码中,我们创建了一个线程池,然后执行一个打印...
Java多线程是Java编程中的重要概念,它允许程序同时执行多个任务,提高了系统的效率和响应性。在Java中,实现多线程主要有两种方式:继承Thread类和实现Runnable接口。接下来,我们将深入探讨这两个方法以及相关的...