- 浏览: 70725 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (76)
- Acitviti (5)
- mybatis (4)
- 大数据 (5)
- servlet (1)
- 负载均衡 (1)
- lucene5.X (3)
- mysql (3)
- 数据库 (2)
- Linux (3)
- Java (10)
- SSO (2)
- spring (3)
- layer (1)
- JAVA多线程 (12)
- 设计模式 (1)
- hadoop (6)
- hdfs (2)
- zookeeper (3)
- yarn (1)
- hive (4)
- sqoop (1)
- redis (1)
- GSON (1)
- velocity (1)
- git (1)
- logback (1)
- shell (9)
- IntellJ idea (1)
- JVM (2)
- maven (1)
最新评论
Future对象在执行使用在外线程中还是同步执行
执行后的结果用时
看到前面的调用使用了future并没有体现出他的优势,所以在使用时候调用还是同步,我改进一下调用优化
改进后执行后的用时
如果在调用时候发生异常情况会怎么样,上边的如果有异常发生会出现消息不能正常处理。看看结果
抛出异常后的执行结果可以看到只要前面有异常就会阻碍后边的程序执行
继续优化异常捕获
看看执行后的日志记录
可以看见执行成功执行的会正常执行完成,想象一下这里我们可以自己处理这些异常,比如将没有执行成功的数据放入消息队列或者放入数据库都可以,等待下次处理或找到调用的问题。
最后版本
现在我们看看最后的执行效果,看着就很舒服了
实际使用中可能会有不同的callable调用,你可以实现自己的callable。
public class CallableFutureTest { ExecutorService executor = Executors.newFixedThreadPool(3); @Test //@Ignore public void testCallable() { long start=System.currentTimeMillis(); try { for (int i = 0; i < 5; i++) { Callable c = new Callable() { public Object call() throws Exception { Boolean random = new Random().nextBoolean(); System.out.println(Thread.currentThread().getName() + "任务启动" + random); Thread.sleep(3000); return random; } }; Future<Boolean> f = executor.submit(c); if (!f.get()) { System.out.println("执行continue操作" + f.get()); continue; } System.out.println("执行后插入数据"); } System.out.println("执行时间最后用时-------------------------"+(System.currentTimeMillis()-start)); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } executor.shutdown(); } }
执行后的结果用时
Connected to the target VM, address: '127.0.0.1:50960', transport: 'socket' pool-1-thread-1任务启动true 执行后插入数据 pool-1-thread-2任务启动false 执行continue操作false pool-1-thread-3任务启动true 执行后插入数据 pool-1-thread-1任务启动false 执行continue操作false pool-1-thread-2任务启动false 执行continue操作false 执行时间最后用时-------------------------14979
看到前面的调用使用了future并没有体现出他的优势,所以在使用时候调用还是同步,我改进一下调用优化
public class CallableFutureTest { ExecutorService executor = Executors.newFixedThreadPool(3); @Test public void testCallable() { long start=System.currentTimeMillis(); //创建多个线程的返回值 List<Future> list = Lists.newArrayList(); try { for (int i = 0; i < 5; i++) { Callable c = new Callable() { public Object call() throws Exception { Boolean random = new Random().nextBoolean(); System.out.println(Thread.currentThread().getName() + "任务启动" + random); Thread.sleep(3000); return random; } }; Future<Boolean> f = executor.submit(c); list.add(f); } for (Future<Boolean> future : list) { if (!future.get()) { System.out.println("执行continue操作" + future.get()); continue; } System.out.println("执行后插入数据"); } System.out.println("执行时间最后用时-------------------------"+(System.currentTimeMillis()-start)); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } executor.shutdown(); } }
改进后执行后的用时
Connected to the target VM, address: '127.0.0.1:52304', transport: 'socket' pool-1-thread-1任务启动true pool-1-thread-2任务启动true pool-1-thread-3任务启动true pool-1-thread-3任务启动true 执行后插入数据 执行后插入数据 执行后插入数据 pool-1-thread-2任务启动false Disconnected from the target VM, address: '127.0.0.1:52304', transport: 'socket' 执行后插入数据 执行continue操作false 执行时间最后用时-------------------------6018
如果在调用时候发生异常情况会怎么样,上边的如果有异常发生会出现消息不能正常处理。看看结果
@Test public void testCallable() { long start = System.currentTimeMillis(); //创建多个线程的返回值 List<Future> list = Lists.newArrayList(); for (int i = 0; i < 5; i++) { Callable c = new Callable() { public Object call() throws Exception { Boolean random = new Random().nextBoolean(); System.out.println(Thread.currentThread().getName() + "任务启动" + random); Thread.sleep(2000); if (!random) { throw new InterruptedException("执行线程被打断异常"); } return random; } }; Future<Boolean> f = executor.submit(c); list.add(f); } try { for (Future<Boolean> future : list) { if (!future.get()) { System.out.println("执行continue操作" + future.get()); continue; } System.out.println("执行后插入数据"); } } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } System.out.println("执行时间最后用时-------------------------" + (System.currentTimeMillis() - start)); executor.shutdown(); }
抛出异常后的执行结果可以看到只要前面有异常就会阻碍后边的程序执行
pool-1-thread-1任务启动false pool-1-thread-2任务启动false pool-1-thread-3任务启动false pool-1-thread-2任务启动false pool-1-thread-3任务启动true 执行时间最后用时-------------------------2015 java.util.concurrent.ExecutionException: java.lang.InterruptedException: 执行线程被打断异常 Caused by: java.lang.InterruptedException: 执行线程被打断异常
继续优化异常捕获
@Test public void testCallable() { long start = System.currentTimeMillis(); //创建多个线程的返回值 List<Future> list = Lists.newArrayList(); for (int i = 0; i < 5; i++) { Callable c = new Callable() { public Object call() throws Exception { Boolean random = new Random().nextBoolean(); System.out.println(Thread.currentThread().getName() + "任务启动" + random); Thread.sleep(2000); if (!random) { throw new InterruptedException("执行线程被打断异常"); } return random; } }; Future<Boolean> f = executor.submit(c); list.add(f); } for (Future<Boolean> future : list) { try { if (!future.get()) { System.out.println("执行continue操作" + future.get()); continue; } System.out.println("执行后插入数据"); } catch (InterruptedException e) { System.out.println("-----------------------------执行中途有异常出现InterruptedException"); e.printStackTrace(); } catch (ExecutionException e) { System.out.println("-----------------------------执行中途有异常出现ExecutionException"); e.printStackTrace(); } } System.out.println("执行时间最后用时-------------------------" + (System.currentTimeMillis() - start)); executor.shutdown(); }
看看执行后的日志记录
pool-1-thread-1任务启动false pool-1-thread-2任务启动true pool-1-thread-3任务启动true pool-1-thread-3任务启动true pool-1-thread-2任务启动false -----------------------------执行中途有异常出现ExecutionException 执行后插入数据 执行后插入数据 java.util.concurrent.ExecutionException: java.lang.InterruptedException: 执行线程被打断异常 Caused by: java.lang.InterruptedException: 执行线程被打断异常 执行后插入数据 java.util.concurrent.ExecutionException: java.lang.InterruptedException: 执行线程被打断异常 Caused by: java.lang.InterruptedException: 执行线程被打断异常 Disconnected from the target VM, address: '127.0.0.1:55843', transport: 'socket' -----------------------------执行中途有异常出现ExecutionException 执行时间最后用时-------------------------4028
可以看见执行成功执行的会正常执行完成,想象一下这里我们可以自己处理这些异常,比如将没有执行成功的数据放入消息队列或者放入数据库都可以,等待下次处理或找到调用的问题。
最后版本
@Test public void testCallable() { long start = System.currentTimeMillis(); //创建多个线程的返回值 List<Future> list = Lists.newArrayList(); for (int i = 0; i < 5; i++) { Callable c = new Callable() { public Object call() throws Exception { Boolean random = new Random().nextBoolean(); System.out.println(Thread.currentThread().getName() + "任务启动" + random); Thread.sleep(2000); if (!random) { throw new InterruptedException("执行线程被打断异常"); } return random; } }; Future<Boolean> f = executor.submit(c); list.add(f); } for (Future<Boolean> future : list) { try { if (!future.get()) { System.out.println("执行continue操作" + future.get()); continue; } System.out.println("执行后插入数据成功"); } catch (InterruptedException e) { System.out.println("将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现InterruptedException"); continue; } catch (ExecutionException e) { System.out.println("将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException"); continue; } } System.out.println("执行时间最后用时-------------------------" + (System.currentTimeMillis() - start)); executor.shutdown();//记住这里在使用完后一定要关闭避免引起资源的浪费和死锁 }
现在我们看看最后的执行效果,看着就很舒服了
Connected to the target VM, address: '127.0.0.1:56951', transport: 'socket' pool-1-thread-1任务启动true pool-1-thread-3任务启动false pool-1-thread-2任务启动false 执行后插入数据 pool-1-thread-1任务启动false pool-1-thread-3任务启动true 将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException 将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException Disconnected from the target VM, address: '127.0.0.1:56951', transport: 'socket' 将异常数据记录到mq或数据库或做补充异步操作-----------------------------执行中途有异常出现ExecutionException 执行后插入数据 执行时间最后用时-------------------------4013
实际使用中可能会有不同的callable调用,你可以实现自己的callable。
发表评论
-
在多线程使用之ThreadLocal
2017-01-07 19:35 309public class Test { publ ... -
控制线程数量之-Semaphore
2016-12-12 12:15 330使用Semaphore的简单例子 ... -
Java多线程设计
2016-08-12 10:33 824操作系统在运行一个程 ... -
“JUC原子类”之 AtomicLong原子类-02
2016-08-11 10:21 419AtomicLong是作用是对长整 ... -
“JUC原子类”框架-01
2016-08-11 10:08 350根据修改的数据类型,可以将JUC包中的原子操作类可以分为4类。 ... -
使用多线程拆分文件下载
2016-04-13 13:59 628首先我们从任意的一个地方获得资源,考虑到你的带宽创建线程 我们 ... -
多线程死锁问题简单案例
2016-04-08 16:25 502多线程案例其实也就是一句话,我获得一个线程资源不释放,又要获得 ... -
在多线程使用volatile关键字
2016-04-08 16:15 424构建了100个线程, Volati ... -
java线程池
2015-09-09 18:30 333线程执行是好但是线程多了也是会很费空间的所以我们要控制线程的数 ... -
线程范围内数据共享
2015-09-09 16:34 375java实现线程范围内数据共享: Thread.crruntT ... -
多线程简单设计
2015-09-09 10:53 299线程直接的通信:通过管道流进行简单的交互 public cla ...
相关推荐
线程池管理和多线程上传是并发编程中的一个重要实践,特别是在大数据传输和网络服务中。在Java等编程语言中,线程池通过有效地管理和复用线程资源,避免了频繁创建和销毁线程带来的开销,提升了系统性能。下面将详细...
本篇文章将深入探讨如何通过实现后台预读线程来优化多线程任务,提高用户界面的响应速度和整体应用体验。 首先,了解什么是预读。预读是一种策略,它在用户实际需要数据之前就开始加载,旨在减少等待时间,提高流畅...
8. **性能调优**:合理设置线程池大小、考虑使用NIO(非阻塞I/O)以减少线程等待时间、监控系统资源使用情况,都是优化多线程文件传输性能的关键。 9. **并发工具类**:`CountDownLatch`、`CyclicBarrier`和`...
本主题将深入探讨如何使用多线程来优化文件的读取和写入过程,以及需要注意的相关问题。 首先,我们需要理解单线程与多线程在文件操作中的区别。在单线程环境下,文件读写通常是顺序执行的,这意味着如果一个任务...
此外,需要注意的是,多线程环境下可能存在竞态条件、死锁等问题,需要合理使用`synchronized`关键字或`Lock`接口来保证数据的一致性和安全性。另外,适当的错误处理和日志记录也是必不可少的,以确保程序的健壮性。...
总之,通过合理地封装和使用线程池,开发者可以更好地控制多线程环境,提高系统的稳定性和性能。在实际项目中,我们应该根据具体的需求选择合适的线程池配置,并对其进行监控和调优,确保系统的高效运行。
在IT领域,多线程是程序设计中的一个重要概念,尤其对于服务器端开发和高并发应用来说,理解并熟练掌握多线程技术至关重要。本资源包针对初学者提供了全面的多线程学习资料,旨在帮助你快速入门并解决实际开发中的...
分段下载则是在多线程的基础上,允许用户暂停和恢复下载,提高了用户体验。在SpringBoot中,我们可以通过HTTP协议的`Range`头字段来实现这一功能。当客户端请求文件时,它可以在请求头中包含`Range`字段,如`Range: ...
在IT领域,多线程是并发处理任务的关键技术,尤其在读取大文件时,能够显著提高程序的执行效率。本文将围绕“多线程读取文件”这一主题,结合给定的标签“源码”和“工具”,深入探讨如何在Java等编程语言中实现这一...
3. **数据库连接池**:为了优化数据库连接的创建和释放,可以使用连接池(如C3P0、HikariCP等),它们提供预配置的数据库连接,供多线程共享使用,减少了连接的创建和关闭时间。 4. **事务管理**:多线程环境下,...
7. **线程性能优化**:如何通过合理的设计和配置来优化多线程程序的性能,例如避免过度同步、减少上下文切换、利用并发容器等。 8. **实战案例**:书中应该会包含一些实际的多线程编程案例,帮助读者将理论知识应用...
4. **并发工具类**:Java的并发包(java.util.concurrent)包含许多高效并发工具,如CountDownLatch、CyclicBarrier、Future和Callable,它们在多线程编程中扮演重要角色。 5. **并发集合**:线程安全的集合类,如...
9. **线程性能调优**:优化多线程程序涉及许多方面,包括合理设置线程数量、避免过度同步、减少上下文切换、使用适当的并发工具等。性能测试和监控也是优化过程的关键部分。 10. **实战案例分析**:通过分析和解决...
在Java编程中,多线程下载文件是一种优化大文件下载速度和效率的技术。它通过将一个大文件分割成多个小部分,然后同时启动多个线程分别下载这些部分,从而达到加速下载的效果。以下是对这个主题的详细解释: 1. **...
在IT行业中,多线程并发处理数据是一种常见的优化策略,特别是在大数据处理、网络服务和分布式系统中。通过并发,可以充分利用多核处理器的计算能力,提高程序执行效率,缩短任务的总体完成时间。本篇文章将深入探讨...
Java多线程技术在爬虫应用中的重要性不言而喻,它能显著提升图片抓取的效率。本文将深入探讨如何使用Java实现多线程爬虫,以及压缩包中的三个示例案例。 首先,我们需要了解Java中的多线程概念。在Java中,通过创建...
了解这些状态有助于调试和优化多线程程序。 7. 死锁问题: 当两个或更多线程相互等待对方释放资源时,就会发生死锁。避免死锁的关键是避免循环等待条件和合理设置锁的顺序。 8. 守护线程(Daemon Thread): ...
多线程性能优化涉及线程池的合理配置、减少上下文切换、避免阻塞操作、使用非阻塞数据结构等。合理的线程数量应考虑系统资源和任务特性,过少可能浪费资源,过多则可能导致上下文切换开销增大。 通过学习《多线程...
在 Java 中,多线程是并发编程的重要概念,它允许程序同时执行多个任务,从而提高系统效率...在后续的学习中,我们将进一步探讨高级多线程技术,如线程池的优化、线程同步机制的使用,以及在实际应用中的秒杀系统实现。
在`基于Java的多线程快速排序设计与优化.pdf`文档中,读者可以期待学习到如何使用Java的并发库来实现多线程快速排序,包括线程池的配置、任务的提交、并行度的选择以及优化技巧等。此外,文档可能还会包含实际代码...