线程 -- 26




1 2 3
概述前面我们介绍了 Executor 框架Executor 框架及线程池的使用利用 Executor 框架,我们可以实现多个线程的并发调用基于 Executor 框架,java 提供了 ThreadPoolExecutor 实现了一个灵活、稳定的线程池,允许用户各种定制,同时,他还可以通过构造方法实例化一个对象来让用户根据自己的需求定制化该对象的操作 ThreadPoolExecutor 的创建ThreadPoolExecutor 的构造方法public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { ... }  通过上面的构造方法,我们就可以轻松创建一个线程池,他有下列参数:corePoolSize -- 线程池目标大小,即在没有任何任务时的线程池大小,
#读书笔记    #技术帖    #线程    #thread   
概述让一个任务或线程启动很容易,但有时我们需要中止线程的执行,但这并不容易,因为 java 并没有提供任何机制来安全地终止线程本篇日志中,我们就来介绍一下 java 线程退出的几种方式 使用 volatile 类型参数保存取消状态由于线程间共享的特性,可以通过使用一个共享的 volatile 成员实现取消状态的保存,每隔一段时间,线程检查该成员的值判断是否应该退出这是一种常见的协作式机制,让取消任务的线程遵循一种协商好的协议package com.techlog.test.service; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** *
#读书笔记    #技术帖    #龙潭书斋    #线程   
Runnable 与 Callable上一篇日志中,我们设计了一个使用 ExecutorService 与 Runnale 接口创建线程的例子Executor 框架及线程池的使用此前我们介绍过 Runnable 与 Callable 的区别,Runnable 接口的 run 方法不能抛出异常也不具有返回值,而实际的使用中,我们常常需要在并发过程中获取每个线程的返回值,这时我们就需要 Callable 接口 使用 Future 收集线程执行结果最基本的线程执行结果收集方法是使用 Future 对象:package com.techlog.test.service; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executo
#技术帖    #龙潭书斋    #线程    #thread   
概述延迟任务就是诸如“在 100ms 以后执行”这样的任务,而周期任务则是“每 10ms 执行一次”这样的任务延迟任务与周期任务通常通过 Timer 类负责实现和管理,但是 Timer 类是基于绝对时间而不是相对时间的调度机制,系统时钟的变化会直接影响到 Timer 的执行结果,这是 Timer 的一个明显的缺陷,另一个缺陷在于 Timer 在执行所有定时任务时只会创建一个线程,所有任务的调度延迟时间都是基于上一个任务的结束时间,这样如果某个任务执行时间过长,那么将会破坏其他任务的执行,同时,一旦任务抛出了一个未知的异常,由于 Timer 线程不捕获异常也并不会尝试恢复,因此他会彻底停止执行和调度,这个问题通常被称为“线程泄漏”ScheduledThreadPoolExecutor 是替代 Timer 的一个比较好的组件,他是通过相对时间进行控制的,不依赖于系统时钟,同时任务的每次执行时间都是基于上一次任务的开始时间计算,结合并发的特性,实现了每次调度不依赖于每次实际的任务执行时间,通过 Executors 对象的工厂方法 newScheduledThreadPoo
#技术帖    #龙潭书斋    #线程    #线程池   
概述前面的日志中,我们主要介绍了 java 并发编程的基本内容和一些基本工具类我们已经知道,很多情况下,单线程线性执行的效率是不可以接受的,而为每个任务都创建线程,可能会无限制的创建下去,资源消耗会异常显著,同时,线程生命周期的开销非常高,不断创建与销毁造成了不必要的代价,而 JVM 还有这 thread 数、栈大小的限制,无线分配线程下去会很容易抛出 OutOfMemoryError,而这样的错误是非常危险的因此,在一定范围内,增加线程可以提高系统吞吐量,但如果超出了这个范围,再创建更多线程只会降低程序的执行速度,并且可能造成整个应用程序的崩溃很多时候,在原型设计和开发阶段,无线创建线程的模型可以很完美的运行,但是在高负载下运行或有人攻击你的接口的时候,这个隐患才会爆发出来 线程池此前,我们介绍过如何通过有界队列来防止高负荷的应用程序耗尽内存:java 中线程安全的容器类线程池则是另一种十分简化的线程管理工具 与上述模式相比,线程池具有显而易见的优势,顾名思义,线程池是一个缓存工作线程的资源池,当请求到来,通常无需重新创建线程,而是直接使用池中的线程,这样就减少了创建和销毁线程的巨大开销,同时也提高了响应速度通过调整线程池中线程数的多少,可以有效地保持处理器的忙碌状态,充分利用资源,也可以防
#技术帖    #龙潭书斋    #线程    #thread   

200x200


概述上一篇日志中,我们介绍了 java 并发编程中的线程安全容器类java 中线程安全的容器类本篇日志中,我们介绍一下 java 中除此之外的其他同步工具类&n

#技术帖    #龙潭书斋    #线程    #thread   

200x200


概述java 线程状态通常包括以下几种:创建(new)就绪(runnable)运行(running)阻塞(blocked)time waitingwaiting消亡(dead)当需

#技术帖    #技术分享    #线程    #sleep   
概述java 在类库设计的过程中,对线程安全做了额外的考虑,因此诞生了丰富的线程安全容器类以及用于协调多个相互写作的线程控制流的同步工具类,特别是在 java5 和 java6 中引入了一些新模块,用来构造并发应用程序的一些常用模式 同步容器类众所周知,HashMap 和 ArrayList 等常用的容器类并不是线程安全的,但在单线程模型下,他们有着很好的执行效率早期,java 通过加锁的方式实现了两个线程安全的同步容器类:Vector 和 Hashtable我们也可以使用 java 类库中提供的 Collections 类的 synchronizedXxxx 方法来创建非线程安全容器的同步容器类如:List<Widget> widgetList = Collections.synchronizedList(new ArrayList<Widget>());  同步容器类的问题同步容器类是线程安全的,但是有些情况下需要客户端加锁来保护复合操作常见的复合操作包括:迭代(遍历容器)跳转(找到下一个元素)条件运算虽然同步容器类的所有操作都是线程安全的,但是当其他线程修
#读书笔记    #技术帖    #龙潭书斋    #sync   
概述前面的日志中,介绍了基本的线程安全知识,本篇日志中将介绍用来保证线程安全的设计模式,这是构建大规模工程的基础 在设计线程安全类的过程中,需要包含以下三个基本要素:找出构成对象状态的所有变量找出月梳妆台变量的不变形条件建立对象状态的并发访问管理策略 类的提供者为了保证开发人员对类的分析和维护,必须将包括如何在不违背对象不变性条件或后延条件的情况下访问对象状态在内的同步策略写入正式文档 实例封闭如果对象不是线程安全的,你可以通过多种技术来确保对象只能由单个线程访问,或者通过锁的方式保护对象的所有访问实例封闭机制是一种将对象实例封装到另一个对象中的线程安全设计模式,通过实例封闭与核实的加锁策略结合,可以确保以线程安全的方式调用非线程安全的对象public class PersonSet { private final Set<Person> mySet = new HashSet<Person>(); public synchronized void addPerson(Person p) { mySet.add(p); } public synchronized boolean containsPerson(Person p) { return mySet.contains(p); } } &nb
#技术帖    #龙潭书斋    #sync    #线程   
开头讲一个故事很久以前,公司的老一代程序员(现在都已经离职)在古老的 restlet 框架的基础上创造了一个 Java MVC 框架,一段框架在程序员的手中代代相传,一个传说流传在程序员之间“所有的 controller 都必须打上 scope=prototype 的烙印”,当这个项目流转到我的手上,当时尚不知道 prototype 意味着什么的我在这个项目上种下了一个小小的 bean,打开了上线系统这个魔盒,等待着项目中的这个种子生根发芽,项目早已是饱经线下测试,我自然是胸有成竹,然而,说时迟那时快,客服电话已是纷至沓来,魔盒中的种子释放出的是混乱与灾难,虽是急急回滚,依然造成了一个多小时的线上故障 -- 所有的用户打开我的订单列表,看到的都是别人的订单记一次重大事故 -- 非线程安全框架引发的意外数据共享 如上面的博文中所述,这个真实的案例发生在 2015 年秋季,日志中也介绍了什么是 prototype,虽然项目饱经测试,但是问题依然没能避免,这就是一场线程安全所引发的灾难,也足见并发环境中的问题难以测试和复现那么,难道真的所有的 Controller 都必须加上 sc
#技术帖    #龙潭书斋    #线程    #thread   
1 2 3



京ICP备15018585号