- 浏览: 546012 次
- 性别:
- 来自: 长沙
文章分类
最新评论
-
wocan23:
镜像是不是就是集群里面的从服务器啊
高并发处理方案 -
chenyi0834:
net.sf.ehcache.Cache ehCache=Ap ...
spring+ehCache简单整合使用示例 -
fsh430623:
是一个获取spring容器bean的工具类
spring+ehCache简单整合使用示例 -
hxc985815621:
ApplicationContextUtils是什么?
spring+ehCache简单整合使用示例 -
peixingchen:
你好,楼主,Action里面的CompanyApplyDTO类 ...
jquery+struts1.3.8的ajax上传文件
多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务,通常,每一个任务称为一个线程,它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序。
多进程与多线程的区别:
每个进程拥有自己的一整套变量,而线程则共享数据。
相关接口
•Runnable
◦ 方法 void run()
◦可由Runnable对象构成Thread,不要调用Thread类或者Runable对象的run方法,直接调用run方法,只会执行同一个线程中的任务,而不会启动新的线程。应该调用Thread.start方法,这个方法将创建一个执行run方法的新线程。
•Callable
◦方法 V call() throws Exception;
◦与Runnable类似,但有返回值
•Future
◦方法 V get() throws…
V get(long timeout, TimeUnit unit) throws ….
Void cancle(boolean mayInterupt) //取消计算,如果已经开始根据参数判断是否中断
boolean isCacelled()
boolean isDone() // 还在计算返回false,完成计算返回true
◦保存异步计算的结果,可以启动一个计算,将future对象交给某个线程,然后忘掉它,future对象的所有者在结果计算好之后就可以获得它。
◦第一个get方法的调用被阻塞,直到计算完成。如果在计算完成之前,第二个方法的调用超时,抛出一个timeoutException异常,如果运行该计算的线程被中断,两个方法都将抛出interruptedException,如果计算已经完成,那么get方法立即返回。
◦FutureTask 包装器是一种非常便利的机制,可将Callable转换成future和Runnable,它同时实现二者的接口
Callalbe myComputation = 。。。;
FutureTask task = new FutureTask(myComputation );
Thread t = new Thread(task);
t.start();
.….
V result = task.get();
线程的状态
要获得一个线程的状态,调用getState方法
•新生:当用new操作创建一个新线程时,该线程还没有开始运行,这意味着它的状态是新生。
•可运行:一旦调用start方法,线程处于runnable状态,记住在任何时刻,一个可运行的线程可能正在运行也可能没有运行
•阻塞/等待/计时等待:当线程处于被阻塞或等待状态时,它暂时不活动。它不运行任何代码且消耗最少的资源,直到线程调度器重新激活它。
1.当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态,当所有其他线程释放该锁,并且线程调度器允许本线程持有它的时候,该线程将变成非阻塞状态
2.当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。在调用object.wait方法或者thread.join方法,或者等待lock或condition时就会出现这种情况
3.有几个方法有一个超时参数,调用它们导致线程进入计时等待状态,这一状态将一直保持到超时期满,或者接收到适当的通知。
•终止:两个原因导致终止
1.因为run方法正常退出而自然死亡 (当线程的run方法执行方法体中最后一条语句后,并经由执行return语句返回时)
2.因为一个没有捕获的异常终止了run方法而意外死亡
没有一个状态叫做中断,中断方法interrupt只是用来申请,当调用该方法时,线程的中断状态被置位。每个线程都应该不时地检查这个标志,以判断线程是否被中断。
如果线程被阻塞,就无法检测中断状态。当一个被阻塞的线程(调用sleep或者wait)上调用interrupt方法时,阻塞调用将会被InterruptedException异常中断。被中断的线程可以决定如何响应中断。
如果在中断状态被置位时调用sleep方法,它不会休眠,相反,它将清除这一状态并抛出InterruptedException。因此如果你的循环调用sleep,不会检测中断状态,应捕获InterruptException异常
线程的属性
•优先级:每一个线程有一个优先级,默认情况下,一个线程继承他的父线程的优先级。每当线程调度器有机会选择新线程时,它首先选择具有较高优先级的线程。Yield 方法导致当前执行线程处于让步状态,如果有其它的可运行线程具有至少与此线程同样高的优先级,那么这些线程接下来会被调用。
•守护线程:setDaemon(true)可将线程转换为守护线程。守护线程应该永远不去访问固定资源,如文件,数据库,因为它会在任何时刻甚至在一个操作的中间发生中断。
同步
•锁对象ReentrantLock
◦结构: myLock.lock();
try {}
finally{ myLock.unlock(); }
….
Lock myLock= new ReentrantLock();
◦这一结构确保任何时刻,只有一个线程进入临界区,一旦一个线程封锁锁对象,其他任何线程都无法通过lock语句,当其他线程调用locka时,它们被阻塞,直到第一个线程释放锁对象。
◦锁是可重入的,因为线程可以重复地获得已经持有的锁,锁保持一个持有计数来跟踪对lock方法的嵌套调用,线程在每一次调用lock都要调用unlock来释放锁。
•条件对象
◦结构:myLock.lock();
try{
while(! Ok to proceed)
{ myCondition.await(); } //当前线程被阻塞,并放弃了锁,进入该条件的等待集
do things
myCondition.signalAll(); //解除因为这一条件而等待的所有线程,这些线程竞争后,被激活的线程从阻塞点开始执行程序
}
finally{ myLock.unlock(); }
….
Lock myLock= new ReentrantLock();
Condition myCondition =myLock.newCondition();
◦一个锁对象可以有一个或多个相关的条件对象。
•synchronized关键字
◦结构:public synchronized void method()
{
while(! Ok to procee)
wait();
do things
notifyAll();
}
◦Java中的每一个对象都一个内部锁,如果一个方法用synchronized 声明,那么对象的锁将保护整个方法,也就是说,要调用该方法,线程必须获得内部的对象锁。
◦内部对象锁只有一个相关条件,wait方法放置一个线程到等待集中,nogifyAll方法解除等待线程的阻塞状态
相当于condition中的await和signalAll
◦将静态方法声明为synchronized 也是合法的,如果调用这种方法,该方法获得相关类对象的内部锁,因此没有其他线程可以调用同一个类的这个或任何其他的同步静态方法。
•同步阻塞
◦结构:synchronized(obj)
{ 。。。
}
Object obj = new Object();
•Volatile域
◦结构: public boolean isDone(){return done;}
public void setDone(){done = true;}
private volatile boolean done;
◦volatile关键字为实例域的同步访问提供了一种免锁机制,如果声明一个域为volatile,那么编译器和虚拟机就知道该域是可能被另一个线程并发更新的。
◦volatile变量不能提供原子性 例如:
public void flipdone() { done = !done ;} //not atomic 不能确保改变域中的值
◦在这样一种非常简单的情况下,可以使用java.util.concurrent.atomic中提供的包装器类,用于原子的整数,浮点数,数组等。该类有get和set方法,确保是原子的。该实现使用有效的机器指令,在不使用锁的情况下确保原子性。
•锁测试与超时
◦tryLock试图申请一个锁,在成功获得锁后返回true,否则立即返回false,而且线程可以立即离开做其他事情。
◦调用tryLock时可使用超时参数。lock方法不能被中断,如果出现死锁,lock方法将无法终止。然而如果调用带超时参数的tryLock,那么如果线程在等待期间被中断,将抛出InterruptedException,将允许打破死锁。
◦lockInterruptlibly相当于一个超时设为无限的tryLock方法
◦在等待一个条件await时,也可以设置超时
•读/写锁ReentrantReadWriteLock
◦结构: private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock ();
private Lock readLock = rwl.readLock();
private Lock writeLock = rwl.writeLock();
◦readLock:得到一个可以被多个读操作共用的读锁,但会排斥所有写操作
◦writeLock:得到一个写锁,排斥所有其他所有读操作和写操作。
阻塞队列
•对于许多线程问题,可以通过使用一个或多个队列以优雅的且安全的方式将其形式化。生产者线程向队列插入元素,消费者线程则取出它们。使用队列,可以安全地从一个线程向另一个线程传递数据。在协调多个线程之间的合作时,阻塞队列是一个有用的工具。
•阻塞队列的方法分为3类:
1.put和take:当试图向满的队列中体添加,或从空的队列中移出元素时,导致线程阻塞。用于将队列当做线程的管理工具来使用。
2.add,remove和element,当试图向满的队列中体添加,或从空的队列中移出元素时抛出异常。
3.offer,poll和peek,当试图向满的队列中体添加,或从空的队列中移出元素时如果不能完成任务,只是给出一个错误提示(返回null),而不会抛出异常。
•阻塞队列的几个变种:
1.LinkedBlockingQueue : 没有上边界
2.ArrayBlockingQueue :构造时需要指定容量
3.priorityBlockingQueue:是一个带优先级的队列,而不是先进先出队列
4.DelayQueue:包含实现Delayed接口的对象
线程安全的集合
•阻塞队列也是线程安全的集合。
•其它集合:
1.ConcurrentHashMap : 有相应的方法用于原子性的关联插入以及关联删除 (散列映像表)
2.ConcurrentSkipListSet : 有序映像表
3.ConcurrentLinkedQueue : 无边界非阻塞队列
4.ConcurrentSkipListMap: 有相应的方法用于原子性的关联插入以及关联删除
•CopyOnWriteArrayList 和 copyOnWriteArraySet 是线程安全的集合。其中所有的修改线程对底层数组进行复制。如果在集合上进行迭代的线程超过修改的线程数,这样的安排是很有用的。当构建一个迭代器的时候,它包含一个对当前数组的引用,如果数组后来被修改了,迭代器仍然引用旧数组。
•Vector和HashTable是线程安全的,但后被弃用,取而代之的是ArrayList和HashMap,它们不是线程安全的。任何集合类通过使用同步包装器变成线程安全的。
List synchArrayList = Collections.synchronizedList(new ArrayList());
Map SynchHashMap = Collections.synchronizedMap(new HashMap());
结果集合的方法使用锁加以保护,提供了线程的安全访问。
如果在另一个线程可能进行修改时,要对集合进行迭代,仍需要使用同步阻塞,因为如果迭代过程中,别的线程修改该集合,迭代器会失效,抛出ConcurrentModificationException。最好使用java.utile.concurrent中定义的集合,不使用同步包装器,有一个例外经常被修改的数组列表,在那种情况下,同步的arrayList可以胜过copyOnWriteArrayList.
执行器
构建一个新的线程是有一定代价的,因为涉及与操作系统的交互。如果程序中创建了大量的生命周期很短的线程,应该使用线程池。一个线程池中包含许多准备运行的空闲线程,将Runnable对象交给线程池,就会有一个线程调用run方法。当run方法退出时,线程不会死亡,而是在池中准备为下一个请求提供服务。
•执行器(Executor)类有许多静态工厂方法用来构建线程池:
1.newCachedThreadPool :对于每个任务,如果有空闲线程可用,立即让它执行任务,如果没有则创建一个新线程。
2.newFixedThreadPool :构建一个具有固定大小的线程池,如果提交的任务数多于空闲的线程数,那么把得不到服务的任务放置到队列中。
3.newSingleThreadExecutor:是一个退化了的大小为一个线程池,由一个线程执行提交的任务,一个接着一个。
4.3个方法的返回值都是实现了ExecutorService接口的ThreadPoolExecutor类的对象。
5.传递Runnable或者Callable对象的方法:
i.Future submit(Runnable task)
ii.Future submit(Runnable task,T result)
iii.Future submit(Callable task)
6.调用shutdown方法启动线程池的关闭序列,被关闭的执行器不再接受新的任务,当所有的任务都完成之后,线程池中的线程死亡。shutdownNow取消尚未开始的所有任务并试图中断正在运行的线程
•预订执行(ScheduledExecrtorService)接口具有为预订执行或重复执行任务而设计的方法,它是一种允许使用线程池机制的java.utile.timer的泛化。
1.newScheduledthreadPool
2.newSingleThreadScheduledExecutor
3.二者可以预订Runnable或Callable在初始的延迟之后之运行一次,也可以预订一个Runnable对象的周期性地运行
•控制任务组
1.invokeAny方法提交所有对象到一个Callable对象的集合中,并返回某个已经完成了的任务的结果,但是无法知道返回的究竟是哪个任务的结果(适用于多个线程处理,其中一个完成,则停止所有的情况,如搜索)
2.invokeAll方法提交所有对象到一个Callable对象的集合中,并返回一个future对象的列表,代表所有任务的解决方案。
3.ExecutorCompletionService 对结果按照可获得的顺序保存起来,然后进行处理
ExecutorCompletionService service = new ExecutorCompletionService (executor);
for(Callalbe task :tasks ) service.submit(task);
for(int i=0;i<task.size();i++)
{
processFuture(service.take().get());
}
发表评论
-
最新idea2020注册码永久激活(激活到2100年)
2020-03-23 15:10 3最新idea2020注册码永久激活(激活到2100年) ... -
Java字符串通配符验证算法
2019-10-17 17:08 688因程序中要用到通配符匹配方法 ,网上找了一些,不如人意,就自己 ... -
springjdbc的对象映射与命名参数问题
2016-01-07 09:24 1740springjdbctemplate ... -
mysql数据库主从复制配置
2015-08-22 15:58 1835最近研究了一下mysql, ... -
读取request将参数文件
2015-06-16 16:00 898读取时很重要一点是 inputStream.read() ... -
Jackson库 简单使用
2014-10-11 12:03 698Jackson在json返回时,据说效率最高最 ... -
JAVA 日期格式 本地语言环境设置
2014-08-15 11:56 858有时候机器的本地语言导致取得的结果与实际需求显示的内容不同, ... -
通过深克隆将复制数据到另一个对象
2014-07-22 16:53 942想将一个对象的数据复制到另一个对象上面,用BeanUtil ... -
fmt:formatDate 标签关于时间简单使用
2014-07-10 11:10 906jstl标签的功能还是十分强大,这格式标签简单好用,我这里分 ... -
面向对象设计原则简单总结
2014-06-29 11:07 1204面向对象设计原则其实大家谈得太多了,我可以 ... -
正则表达式处理img标签
2014-05-29 11:41 10546文章内容中包含有<img>标签内容,但有时候不 ... -
获取上传文件格式
2014-04-09 15:11 1042java准确获取各种上传文件包括图片文件的格式 ... -
springmvc服务端数据验证的自定义验证与扩展使用
2014-02-20 11:37 2024... -
springmvc服务端验证
2014-02-20 11:26 4588... -
java去掉全角半角空格
2013-11-30 17:25 1273有时候需要在后台来处理全解半解空格, ... -
SecurityContext is empty or contents are anonymous处理
2013-11-30 10:14 6323最近用swfupload做上传,在火狐浏览器下上传操作时 出 ... -
SpringMVC Controller 综合介绍 一、简介
2013-11-08 17:48 1036SpringMVC Controller 综合介绍 一 ... -
spring+ehCache简单整合使用示例
2013-11-08 10:31 19711下面介绍一下简单使用的配置过程:ehcache.jar及spr ... -
springmvc拦截器使用小结
2013-09-28 11:59 1632springmvc拦截器使用小结 想做个session拦截验 ... -
简单防sql注入攻击数据库处理代码示例
2013-08-13 16:13 1680sql注入,就是在传入的参数中设置sql陷阱,从而引发恶意的数 ...
相关推荐
简介:JavaInterview只是根据个人经验以及参考网络整理而成的Java知识点整合,固然不可能完全正确,欢迎大家指正。注:笔记中涉及到的图片文件,除非除非知道知道出处的会标,否则其他均匀来源网络(即使我偶尔原创...
除了上述模块,文章还强调了对于面试题的深入解析和代码案例的提供,这对于面试者理解知识点、整理思路和表达能力的培养是至关重要的。文章提到,通过这些面试题,求职者可以查漏补缺,为技术面试做充分的准备。同时...
6. **多线程**:如何创建和管理线程,以及同步和互斥的概念。 7. **泛型**:如何使用泛型来提高代码的类型安全性和重用性。 8. **接口与抽象类**:它们的区别和使用场景。 9. **设计模式**:可能包含一些常见设计...
【项目资源】: 包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。 包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】: 所有源码都经过严格测试,可以直接运行。 功能在确认正常工作后才上传。 【适用人群】: 适用于希望学习不同技术领域的小白或进阶学习者。 可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】: 项目具有较高的学习借鉴价值,也可直接拿来修改复刻。 对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】: 有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 鼓励下载和使用,并欢迎大家互相学习,共同进步。。内容来源于网络分享,如有侵权请联系我删除。另外如果没有积分的同学需要下载,请私信我。
精选毕设项目-宅男社区
精选毕设项目-扫描条形码
配网两阶段鲁棒优化调度模型 关键词:两阶段鲁棒优化,CCG算法,储能 仿真算例采用33节点,采用matlab+yalmip+cplex编写,两阶段模型采用CCG算法求解。 模型中一阶段变量主要包括01变量和无功优化变量,核心变量主要存在于二阶段,因此在叠加二阶段变量优化过程中更容易得到最优解,所以有限次迭代即得到收敛的结果。 模型以网损为目标,包括功率平衡、网络潮流、电压电流、蓄电池出力以及无功设备出力等约束。 复现《两阶段鲁棒优化的主动配电网动态无功优化》-熊壮壮,具体内容可自行下载了解。
comsol光栅仿真 计算复合波导光栅准BIC增强古斯汉森位移
精选毕设项目-车源宝寻车广场
数字农业产业项目整体解决方案
精选毕设项目-幸运大抽奖
SRS构型七自由度冗余机械臂运动学建模全套matlab代码 代码主要功能: [1]. 基于臂角参数化方法求解机械臂在给定末端位姿和臂角下的关节角度; [2]. 求解机械臂在给定末端位姿下的有效臂角范围,有效即在该区间内机械臂关节角度不会超出关节限位; [3]. 以避关节限位为目标在有效臂角区间内进行最优臂角的选取,进而获取机械臂在给定末端位姿下的最优关节角度。 购前须知: 1. 代码均为个人手写,主要包含运动学建模全套代码; 2. 代码已经包含必要的注释; 包含原理推导文档,不包含绘图脚本以及urdf;
精选毕设项目-微信小程序天气源码
bmjebm-29-6.pdf
chromedriver-linux64_123.0.6273.0
精选毕设项目-腾讯云小程序一站式解决方案
精选毕设项目-仿饿了么
Spring Boot是Spring框架的一个模块,它简化了基于Spring应用程序的创建和部署过程。Spring Boot提供了快速启动Spring应用程序的能力,通过自动配置、微服务支持和独立运行的特性,使得开发者能够专注于业务逻辑,而不是配置细节。Spring Boot的核心思想是约定优于配置,它通过自动配置机制,根据项目中添加的依赖自动配置Spring应用。这大大减少了配置文件的编写,提高了开发效率。Spring Boot还支持嵌入式服务器,如Tomcat、Jetty和Undertow,使得开发者无需部署WAR文件到外部服务器即可运行Spring应用。 Java是一种广泛使用的高级编程语言,由Sun Microsystems公司(现为Oracle公司的一部分)在1995年首次发布。Java以其“编写一次,到处运行”(WORA)的特性而闻名,这一特性得益于Java虚拟机(JVM)的使用,它允许Java程序在任何安装了相应JVM的平台上运行,而无需重新编译。Java语言设计之初就是为了跨平台,同时具备面向对象、并发、安全和健壮性等特点。 Java语言广泛应用于企业级应用、移动应用、桌面应用、游戏开发、云计算和物联网等领域。它的语法结构清晰,易于学习和使用,同时提供了丰富的API库,支持多种编程范式,包括面向对象、命令式、函数式和并发编程。Java的强类型系统和自动内存管理减少了程序错误和内存泄漏的风险。随着Java的不断更新和发展,它已经成为一个成熟的生态系统,拥有庞大的开发者社区和持续的技术创新。Java 8引入了Lambda表达式,进一步简化了并发编程和函数式编程的实现。Java 9及以后的版本继续在模块化、性能和安全性方面进行改进,确保Java语言能够适应不断变化的技术需求和市场趋势。 MySQL是一个关系型数据库管理系统(RDBMS),它基于结构化查询语言(SQL)来管理和存储数据。MySQL由瑞典MySQL AB公司开发,并于2008年被Sun Microsystems收购,随后在2010年,Oracle公司收购了Sun Microsystems,从而获得了MySQL的所有权。MySQL以其高性能、可靠性和易用性而闻名,它提供了多种特性来满足不同规模应用程序的需求。作为一个开源解决方案,MySQL拥有一个活跃的社区,不断为其发展和改进做出贡献。它的多线程功能允许同时处理多个查询,而其优化器则可以高效地执行复杂的查询操作。 随着互联网和Web应用的快速发展,MySQL已成为许多开发者和公司的首选数据库之一。它的可扩展性和灵活性使其能够处理从小规模应用到大规模企业级应用的各种需求。通过各种存储引擎,MySQL能够适应不同的数据存储和检索需求,从而为用户提供了高度的定制性和性能优化的可能性。
精选毕设项目-体育新闻赛事数据
chromedriver-linux64_122.0.6254.0