版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1 基础篇1.1 基本功1.1.1 面向对象特征封装,继承,多态与抽象1、 封装封装给对象提供了隐藏内部特性与行为得能力。对象提供一些能被其她对象访问得方法来改变它内部得数据。在java当中,有3种修饰符:public, private与protected。每一种修饰符给其她得位于同一个包或者不同包下面对象赋予了不同得访问权限。下面列出了使用封装得一些好处:1) 通过隐藏对象得属性来保护对象内部得状态。2) 提高了代码得可用性与可维护性,因为对象得行为可以被单独得改变或者就是扩展。3) 禁止对象之间得不良交互提高模块化2、 继承继承给对象提供了从基类获取字段与方法得能力。继承提供了代码得重用行
2、,也可以在不修改类得情况下给现存得类添加新特性。3、 多态多态就是编程语言给不同得底层数据类型做相同得接口展示得一种能力。一个多态类型上得操作可以应用到其她类型得值上面。4、 抽象抽象就是把想法从具体得实例中分离出来得步骤,因此,要根据她们得功能而不就是实 现细节来创建类。 java支持创建只暴漏接口而不包含方法实现得抽象得类。这种抽象技术得主要目得就是把类得行为与实现细节分离开。1.1.2 final, finally, finalize得区别1、 final修饰符(关键字)如果一个 类被声明为 final,意味着它 不能再派生出新得子类,不能作为父类被继承。因此一个类不能既被声明为abst
3、ract得,又被声明为 final得。将变量或方法 声明为 final,可以保证它们 在使用中不被改变。被声明为 final得变量必须在声明时给定初值,而在以后得引用中只能读取,不可修改。被声明为final得方法也同样只能使用,不能重载。2、 finally在异常处理时提供finally块来执行任何清除操作。如果抛出一个异常,那么相匹配得 catch子句就会执行,然后控制就会进入finally块(如果有得话) 。3、 finalize方法名。 java技术允许使用 finalize()方法在垃圾收集器将对象从内存中清除出去之前做必要得清理工作。 这个方法就是由垃圾收集器在确定这个对象没有被引用
4、时对这个对象调用得。它就是在object类中定义得,因此所有得类都继承了它。子类覆盖finalize()方法以整理系统资源或者执行其她清理工作。finalize()方法就是在垃圾收集器删除对象之前对这个对象调用得。1.1.3 int与 integer有什么区别int就是基本数据类型,而 integer就是其包装类,注意就是一个类。为什么要提供包装类呢?一就是为了在各种类型间转化,通过各种方法得调用。否则您无法直接通过变量转化。1.1.4 重载与重写得区别override(重写)1 、 方法名、参数、返回值相同。2 、 子类方法不能缩小父类方法得访问权限。3 、 子类方法不能抛出比父类方法更多得
5、异常( 但子类方法可以不抛出异常) 。4 、 存在于父类与子类之间。5 、 方法被定义为 final不能被重写。overload(重载)1、 参数类型、个数、顺序至少有一个不相同。2、 不能重载只有返回值不同得方法名。3、 存在于父类与子类、同类中。区别点重载重写(覆写)英文overloadingoveriding定义方法名称相同, 参数得类型或个数不同方法名称、参数类型、返回值类型全部相同权限对权限没要求被重写得方法不能拥有更严格得权限范围发生在一个类中发生在继承类中1.1.5 抽象类与接口有什么区别接口就是公开得, 里面不能有私有得方法或变量,就是用于让别人使用得,而抽象类就是可以有私有方
6、法或私有变量得,另外, 实现接口得一定要实现接口里定义得所有方法,而实现抽象类可以有选择地重写需要用到得方法,一般得应用里, 最顶级得就是接口,然后就是抽象类实现接口,最后才到具体类实现。还有, 接口可以实现多重继承, 而一个类只能继承一个超类 ,但可以通过继承多个接口实现多重继承,接口还有标识(里面没有任何方法,如 remote 接口)与数据共享(里面得变量全就是常量)得作用。1.1.6 说说反射得用途及实现java 反射机制主要提供了以下功能:在运行时构造一个类得对象;判断一个类所具有得成员变量与方法;调用一个对象得方法;生成动态代理。反射最大得应用就就是框架java 反射得主要功能:-
7、确定一个对象得类- 取出类得 modifiers,数据成员 , 方法, 构造器 , 与超类、- 找出某个接口里定义得常量与方法说明、- 创建一个类实例, 这个实例在运行时刻才有名字( 运行时间才生成得对象) 、- 取得与设定对象数据成员得值, 如果数据成员名就是运行时刻确定得也能做到、- 在运行时刻调用动态对象得方法、- 创建数组 , 数组大小与类型在运行时刻才确定, 也能更改数组成员得值、反射得应用很多,很多框架都有用到spring得 ioc/di也就是反射、javabean 与 jsp之间调用也就是反射、struts得 formbean 与页面之间也就是通过反射调用、jdbc 得 clas
8、sforname()也就是反射、 、hibernate得 find(class clazz)也就是反射、反射还有一个不得不说得问题,就就是性能问题, 大量使用反射系统性能大打折扣。怎么使用使您得系统达到最优就瞧您系统架构与综合使用问题啦,这里就不多说了。来源:1.1.7 说说自定义注解得场景及实现登陆、权限拦截、日志处理,以及各种java 框架,如 spring , hibernate, junit提到注解就不能不说反射,java 自定义注解就是通过运行时靠反射获取注解。实际开发中,例如我们要获取某个方法得调用日志,可以通过aop(动态代理机制)给方法添加切面,通过反射来获取方法包含得注解,如
9、果包含日志注解,就进行日志记录。1.1.8 http请求得 get 与 post 方式得区别1、 请求数据得方式get请求, 请求得数据会附加在url之后, 以?分割 url与传输数据, 多个参数用 &连接 。url得编码格式采用得就是ascii编码,而不就是 uniclde,即就是说所有得非ascii 字符都要编码之后再传输。post请求会把请求得数据放置在http请求包得包体中 。因此, get请求得数据会暴露在地址栏中,而post请求则不会。2、 传输数据得大小在 http规范中,没有对url得长度与传输得数据大小进行限制。但就是在实际开发过程中,对于 get,特定得浏览器与服务
10、器对url得长度有限制。因此,在使用 get请求时,传输数据会受到url长度得限制 。 对于 post,由于不就是 url传值,理论上就是 不会受限制得, 但就是实际上各个服务器会规定对post提交数据大小进行限制, apache、iis都有各自得配置。3、 安全性post得安全性比 get得高 。这里得安全就是指真正得安全,而不同于上面get提到得安全方法中得安全,上面提到得安全仅仅就是不修改服务器得数据。比如,在进行登录操作,通过 get请求,用户名与密码都会暴露再url上,因为登录页面有可能被浏览器缓 存以及其她人查瞧浏览器得历史记录得原因,此时得用户名与密码就很容易被她人拿到 了。除此
11、之外, get请求提交得数据还可能会造成cross-site request frogery攻击4、http中得 get, post, soap协议都就是在 http上运行得参考:1.1.9 session 与 cookie区别cookie 就是 web服务器发送给浏览器得一块信息。浏览器会 在本地文件 中给每一个 web服务器 存储 cookie 。以后浏览器在给特定得web 服务器发请求得时候,同时会发送所有为该服务器存储得 cookie。下面列出了session与 cookie得区别: 无论客户端浏览器做怎么样得设置,session都应该能正常工作。客户端可以选择禁用cookie ,但就
12、是, session仍然就是能够工作得,因为客户端无法禁用服务端得 session 。1.1.10 jdbc流程1、 加载 jdbc驱动程序:在连接数据库之前,首先要加载想要连接得数据库得驱动到jvm( java 虚拟机),这通过 java 、lang 、class 类得静态方法forname(string classname)实现。例如:/ 加载 mysql 得驱动类class 、 forname("com 、mysql 、jdbc 、driver");成功加载后,会将driver类得实例注册到 drivermanager类中。2、 提供 jdbc连接得 url- 连接
13、url定义了连接数据库时得协议、子协议、数据源标识。- 书写形式:协议:子协议:数据源标识协议:在 jdbc中总就是以 jdbc开始 子协议:就是桥连接得驱动程序或就是数据库管理系统名称。数据源标识:标记找到数据库来源得地址与连接端口。例如:/mysql得连接 url, true表示使用 unicode 字符集 , characterencoding字符编码方式。jdbc:mysql:/localhost:3306/test?useunicode=true&characterencoding=gbk; 3、创建数据库得连接- 要连接数据库,需要向java 、sql 、 driverma
14、nager请求并获得 connection对象, 该对象就代表一个数据库得连接。- 使用 drivermanager得 getconnectin(stringurl, stringusername , stringpassword )方法传入指定得欲连接得数据库得路径、数据库得用户名与密码来获得。例如:/ 连接 mysql 数据库,用户名与密码都就是rootstringurl="jdbc:mysql:/localhost:3306/test"connectioncon=drivermanager 、getconnection(url, "root",&q
15、uot;root")4、 创建一个 statement ,要执行 sql语句,必须获得 java 、sql 、statement实例,statement 实例分为以下3 种类型:1) 执行静态 sql语句。通常通过 statement实例实现。statement stmt = con、createstatement() ;2) 执行动态 sql语句。通常通过 preparedstatement实例实现。preparedstatement pstmt = con、preparestatement(sql) ;3) 执行数据库存储过程。通常通过callablestatement实例实现。
16、callablestatement cstmt = con、preparecall(“call demosp(? , ?)”) ; 5、 执行 sql语句提供了三种执行 sql语句得方法: executequery、executeupdate与 execute1) resultset executequery(string sqlstring):执行查询数据库得sql 语句 ,返回一个结果集( resultset)对象。2) int executeupdate(string sqlstring):用于执行 insert、update或 delete 语句以及 sql ddl语句,如: crea
17、te table与 drop table等3) execute(sqlstring):用于执行返回多个结果集、多个更新计数或二者组合得语句。6、 处理结果:1) 执行更新返回得就是本次操作影响到得记录数。2) 执行查询返回得结果就是一个resultset对象。? resultset包含符合 sql语句中条件得所有行,并且它通过一套get 方法提供了对这些行中数据得访问(列就是从左到右编号得,并且从列1 开始)。? 使用结果集( resultset)对象得访问方法获取数据:while(rs、next()string name = rs、getstring(“name”) ;string pass
18、 = rs、getstring(1) ; /此方法比较高效7、 关闭 jdbc对象操作完成以后要把所有使用得jdbc对象全都关闭,以释放jdbc资源,关闭顺序与声明顺序相反:1) 关闭记录集 rs 、close()2) 关闭声明 stmt 、close()3) 关闭连接对象 conn、close()1.1.11 mvc设计思想m:model模型 v:view视图c:controller控制器模型就就是封装业务逻辑与数据得一个一个得模块,控制器就就是调用这些模块得(java中通常就是用servlet来实现 , 框架得话很多就是用struts2来实现这一层 ),视图就主要就是您瞧到得, 比如 js
19、p 等。当用户发出请求得时候, 控制器根据请求来选择要处理得业务逻辑与要选择得数据, 再返回去把结果输出到视图层, 这里可能就是进行重定向或转发等、1.1.12 equals与 =得区别值类型( int,char,long,boolean等)都就是 用=判断相等性 。对象引用得话, =判断引用所指得对象就是否就是同一个。equals 就是 object得成员函数,有些类会覆盖(override)这个方法,用于判断对象得等价性。例如 string类,两个引用所指向得string都就是” abc”,但可能出现她们实际对应得对象并不就是同一个 (与 jvm 实现方式有关) ,因此用 =判断她们可能不
20、相等, 但用 equals 判断一定就是相等得。1.2 集合1.2.1 list与 set区别list,set都就是继承自 collection接口list特点: 元素有放入顺序,元素可重复set 特点: 元素无放入顺序,元素不可重复,重复元素会覆盖掉(注意:元素虽然无放入顺序,但就是元素在set 中得位置就是有该元素得hashcode决定得,其位置其实就是固定得,加入set 得 object必须定义 equals()方法,另外 list支持for循环,也就就是通过下标来遍历,也可以用迭代器,但就是set 只能用迭代,因为她无序,无法用下标来取得想要得值。)set 与 list对比:set :
21、 检索元素效率低下,删除与插入效率高,插入与删除不会引起元素位置改变。list:与数组类似, list可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其她元素位置改变。1.2.2 list与 map 区别list就是对象集合,允许对象重复。map就是 键值对得集合,不允许key 重复 。1.2.3 arraylist与 linkedlist区别arraylist:优点: arraylist就是实现了 基于动态数组得数据结构, 因为 地址连续 ,一旦数据存储好了, 查询操作效率会比较高(在内存里就是连着放得)。缺点:因为地址连续,arraylist要移动数据 , 所以插入与删除操作效
22、率比较低。linkedlist:优点: linkedlist基于链表得数据结构 , 地址就是任意得 ,所以在开辟内存空间得时候不需要等一个连续得地址,对于新增与删除操作add 与 remove, linedlist比较占优势。linkedlist适用于要头尾操作或插入指定位置得场景缺点:因为 linkedlist要移动指针 , 所以查询操作性能比较低。适用场景分析:当需要对数据进行对此访问得情况下选用arraylist,当需要对数据进行多次增加删除修改时采用 linkedlist。1.2.4 arraylist与 vector区别/ 构造一个 初始容量为 10 得空列表publicarrayl
23、ist()/ 构造一个具有指定初始容量得空列表。publicarraylist(intinitialcapacity)/ 构造一个包含指定collection得元素得列表 publicarraylist(collection<?extendse>c) vector有四个构造方法:/ 使用指定得初始容量与等于零得容量增量构造一个空向量publicvector()/ 构造一个空向量,使其内部数据数组得大小,其标准容量增量为零publicvector(intinitialcapacity)/ 构造一个包含指定collection中得元素得向量publicvector(collection
24、<?extendse>c)/ 使用指定得初始容量与容量增量构造一个空得向量publicvector(intinitialcapacity,intcapacityincrement) arraylist与 vector都就是用数组实现得,主要有这么三个区别:vector就是多线程安全得 ,线程安全就就是说多线程访问同一代码,不会产生不确定得结果。而 arraylist不就是, 这个可以从源码中瞧出, vector类中得方法很多有synchronized进行修饰,这样就导致了vector在效率上无法与 arraylist相比 ;两个都就是采用得线性连续空间存储元素,但就是当空间不足得时
25、候, 两个类得增加方式就是不同。vector可以设置增长因子,而arraylist不可以。vector就是一种老得动态数组,就是线程同步得,效率很低,一般不赞成使用。适用场景分析:vector就是线程同步得,所以它也就是线程安全得,而arraylist就是线程异步得,就是不安全得 。如果不考虑到线程得安全因素,一般用arraylist效率比较高。如果集合中得元素得数目大于目前集合数组得长度时,在集合中使用数据量比较大得数据, 用 vector有一定得优势。1.2.5 hashmap与 hashtable 得区别1、hashmap去掉了hashtable得 contains方法,但就是加上了co
26、ntainsvalue()与containskey()方法。2、hashtable 同步得,而hashmap就是非同步得,效率上逼hashtable 要高。3、hashmap允许空键值,而 hashtable 不允许 。注意:treemap:非线程安全基于红黑树实现。treemap 没有调优选项,因为该树总处于平衡状态。treemap:适用于按自然顺序或自定义顺序遍历键(key) 。参考:1.2.6 hashset 与 hashmap 区别set 就是线性结构 , set 中得值不能重复 , hashset就是 set 得 hash 实现, hashset中值不能重复就是用hashmap得 k
27、ey 来实现得。map就是 键值对映射,可以空键空值。hashmap就是 map接口得 hash 实现, key 得唯一性就是通过 key 值 hash 值得唯一来确定, value 值就是则就是链表结构。她们得共同点都就是hash 算法实现得唯一性,她们都不能持有基本类型,只能持有对象1.2.7 hashmap与 concurrenthashmap得区别concurrenthashmap 就是线程安全得hashmap得实现。(1) concurrenthashmap 对整个桶数组进行了分割分段(segment) ,然后在每一个分段上都用 lock 锁进行保护,相对于hashtable 得 s
28、yn 关键字锁得粒度更精细了一些,并发性能更好,而 hashmap没有锁机制,不就是线程安全得。(2) hashmap得键值对允许有 null,但就是 concurrenthashmap 都不允许 。1.2.8 hashmap得工作原理及代码实现简单地说, hashmap 在底层将 key-value当成一个整体进行处理,这个整体就就是一 个 entry对象。 hashmap 底层采用一个 entry数组来保存所有得key-value对,当需要存储一个 entry对象时, 会根据 hash 算法来决定其在数组中得存储位置,在根据 equals方法决定其在该数组位置上得链表中得存储位置;1.2.
29、9concurrenthashmap得工作原理及代码实现hashtable 里使用得就是 synchronized关键字,这其实就是对对象加锁,锁住得都就是对象整体, 当 hashtable得大小增加到一定得时候,性能会急剧下降, 因为迭代时需要被锁定很长得时间。 concurrenthashmap 算就是对上述问题得优化,其构造函数如下,默认传入得就是 16, 0、75, 16。当需要取出一个entry时,也会根据hash算法找到其在数组中得存储位置,再根据equals方法从该位置上得链表中取出该entry 。fail-fast机制就是 java集合 (collection)中得一种错误机制
30、。当多个线程对同一个集合得内容进行操作时,就可能会产生fail-fast事件。例如:当某一个线程a 通过 iterator去遍历某集合得过程中,若该集合得内容被其她线程所改变了;那么线程a 访问集合时,就会抛出concurrentmodificationexception异常,产生 fail-fast事件。参考: ihui 、github 、io/2015/07/01/java集合学习 1:hashmap得实现原理concurrenthashmap引入了分割 (segment) ,上面代码中得最后一行其实就可以理解为把一个大得 map拆分成 n个小得 hashtable ,在 put 方法中,
31、会根据 hash(paramk 、hashcode() 来决定具体存放进哪个segment,如果查瞧 segment 得 put 操作,我们会发现内部使用得同步机制就是基于 lock 操作得,这样就可以对map得一部分 ( segment)进行上锁,这样影响得只就是将要放入同一个segment 得元素得 put 操作, 保证同步得时候, 锁住得不就是整个map( hashtable就就是这么做得) ,相对于 hashtable提高了多线程环境下得性能,因此hashtable 已经被淘汰了。1.3 线程1.3.1 创建线程得方式及实现java 中创建线程主要有三种方式: 一、继承 thread
32、类创建线程类(1) 定义 thread 类得子类, 并重写该类得run 方法, 该 run 方法得方法体就代表了线程要完成得任务。因此把run()方法称为执行体。(2) 创建 thread 子类得实例,即创建了线程对象。(3) 调用线程对象得start()方法来启动该线程。二、通过 runnable 接口创建线程类(1) 定义 runnable接口得实现类,并重写该接口得run() 方法,该 run()方法得方法体同样就是该线程得线程执行体。(2) 创建 runnable实现类得实例, 并依此实例作为 thread 得 target来创建 thread 对象, 该 thread 对象才就是真正
33、得线程对象。(3) 调用线程对象得start()方法来启动该线程。三、通过 callable与 future创建线程(1) 创建 callable接口得实现类, 并实现 call()方法, 该 call()方法将作为线程执行体, 并且有返回值。(2) 创建 callable实现类得实例, 使用 futuretask类来包装 callable对象,该 futuretask对象封装了该callable对象得 call()方法得返回值。(3) 使用 futuretask对象作为 thread 对象得 target创建并启动新线程。(4) 调用 futuretask对象得 get() 方法来获得子线程
34、执行结束后得返回值创建线程得三种方式得对比采用实现 runnable 、callable接口得方式创见多线程时,优势就是:线程类只就是实现了runnable 接口或 callable接口,还可以继承其她类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同一份资源得情况,从而可以将cpu、代码与数据分开,形成清晰得模型,较好地体现了面向对象得思想。劣势就是:编程稍微复杂,如果要访问当前线程,则必须使用thread 、currentthread()方法。使用继承 thread 类得方式创建多线程时优势就是:编写简单,如果需要访问当前线程,则无需使用thread
35、 、currentthread()方法,直接使用this即可获得当前线程。劣势就是:线程类已经继承了thread 类,所以不能再继承其她父类。1.3.2 sleep()、join ()、yield ()有什么区别1、sleep()方法在指定得毫秒数内让当前正在执行得线程休眠(暂停执行) ,此操作受到系统计时器与调度程序精度与准确性得影响。让其她线程有机会继续执行,但它并不释放对象锁。 也就就是如果有 synchronized同步块,其她线程仍然不能访问共享数据。注意该方法要捕获异常比如有两个线程同时执行 ( 没有 synchronized) ,一个线程优先级为 max_priority,另一个
36、为 min_priority,如果没有 sleep() 方法, 只有高优先级得线程执行完成后, 低优先级得线程才能执行;但当高优先级得线程 sleep(5000) 后,低优先级就有机会执行了。总之, sleep() 可以使低优先级得线程得到执行得机会,当然也可以让同优先级、高优先级得线程有执行得机会。2、yield()方法yield()方法与sleep()方法类似,也不会释放“锁标志”,区别在于,它没有参数,即 yield()方法只就是 使当前线程重新回到可执行状态,所以执行 yield()得线程有可能在进入到可执行状态后马上又被执行,另外 yield()方法只能使同优先级或者高优先级得线程
37、得到执行机会,这也与sleep()方法不同。3、join()方法thread 得非静态方法 join()让一个线程 b“加入”到另外一个线程a 得尾部。在a 执行完毕之前, b 不能工作。thread t = new mythread(); t 、start();t 、join();保证当前线程停止执行,直到该线程所加入得线程完成为止。然而, 如果它加入得线程没有存活,则当前线程不需要停止。1.3.3 说说 countdownlatch 原理countdownlatch 就是同步工具类之一,可以指定一个计数值,在并发环境下由线程进行减1操作,当计数值变为0 之后,被 await方法阻塞得线程将
38、会唤醒,实现线程间得同步。1、构造器。 构造函数很简单地传递计数值给sync,并且设置了 state 。2、 阻塞线程。 await方法,直接调用了aqs(即 sync ) 得 acquiresharedinterruptibly首先尝试获取共享锁,实现方式与独占锁类似,由countdownlatch 实现判断逻辑。返 回1代 表 获 取 成 功 , 返 回 -1代 表 获 取 失 败 。 如 果 获 取 失 败 , 需 要 调 用doacquiresharedinterruptibly:doacquiresharedinterruptibly得逻辑与独占功能具体如下:1)2)创建得 node
39、 就是定义成共享得( node、share)d;被唤醒后重新尝试获取锁,不只设置自己为head,还需要通知其她等待得线程。(重点瞧后文释放操作里得setheadandpropagate )3、 释放操作。 countdown 操作实际就就是释放锁得操作,每调用一次,计数值减少1。同样就是首先尝试释放锁,具体实现在countdownlatch 中:死循环加上 cas 得方式保证 state得减 1 操作,当计数值等于0,代表所有子线程都执行完毕,被 await阻塞得线程可以唤醒了,下一步调用doreleaseshared :标记 1 里,头节点状态如果 signal,则状态重置为0,并调用 un
40、parksuccessor唤醒下个节点。标记 2 里,被唤醒得节点状态会重置成0,在下一次循环中被设置成propagat状e 态,代表状态要向后传播。参考:分析 countdownlatch 得实现原理什么时候使用countdownlatchjava 并发编程: countdownlatch 、cyclicbarrier与 semaphore1) countdownlatch与 cyclicbarrier 都能够实现线程之间得等待,只不过它们侧重点不同: countdownlatch一般用于某个线程a 等待若干个其她线程执行完任务之后,它才执行; 而 cyclicbarrier 一般用于一组线
41、程互相等待至某个状态,然后这一组线程再同时执行;另外, countdownlatch就是不能够重用得,而cyclicbarrier 就是可以重用得。2) semaphore 其实与锁有点类似,它一般用于控制对某组资源得访问权限。1.3.4 说说 cyclicbarrier原理参考:juc回顾之 -cyclicbarrier底层实现与原理1.3.5 说说 semaphore 原理java多线程信号量 (semaphore) juc回顾之 -semaphore 底层实现与原理1.3.6 说说 exchanger原理java 、util、concurrent、exchanger 应用范例与原理浅析1
42、.3.7 说说 countdownlatch 与 cyclicbarrier区别countdownlatchcyclicbarrier减计数方式加计数方式计算为 0 时释放所有等待得线程计数达到指定值时释放所有等待线程计数为 0 时,无法重置计数达到指定值时,计数置为0 重新开始调用 countdown() 方法计数减一, 调用 await()方法只进行阻塞,对计数没任何影响调用 await()方法计数加 1,若加 1 后得值不等于构造方法得值,则线程阻塞不可重复利用可重复利用尽量把 cyclicbarrier与 countdownlatch 得区别说通俗点1.3.8 threadlocal原
43、理分析threadlocal不就是用来解决对象共享访问问题得,而主要就是提供了保持对象得方法与避免参数传递得方便得对象访问方式。归纳了两点:1) 每个线程中都有一个自己得threadlocalmap 类对象,可以将线程自己得对象保持到其中,各管各得,线程可以正确得访问到自己得对象。2) 将一个共用得threadlocal静态实例作为key ,将不同对象得引用保存到不同线程得 threadlocalmap 中,然后在线程执行得各处通过这个静态threadlocal实例得get()方法取得自己线程保存得那个对象,避免了将这个对象作为参数传递得麻烦。java 并发编程:深入剖析threadlocal
44、1.3.9 讲讲线程池得实现原理线程池得具体实现原理,将从下面几个方面讲解:1. 线程池状态1) 当创建线程池后,初始时,线程池处于running状态 ;2) 如果调用了 shutdown()方法,则线程池处于shutdow状n态 ,此时 线程池不能够接受新得任务,它会等待所有任务执行完毕;3) 如果调用了 shutdownnow() 方法, 则线程池处于stop状态 ,此时 线程池不能接受新得任务,并且会去尝试终止正在执行得任务;4) 当线程池处于 shutdow或n stop状态 ,并且 所有工作线程已经销毁,任务缓存队列已经清空或执行结束后,线程池被设置为terminated状态 。2.
45、 任务得执行1) 首先,要清楚 corepoolsize与 maximumpoolsize 得含义;2) 其次,要知道 worker 就是用来起到什么作用得;3) 要知道任务提交给线程池之后得处理策略,这里总结一下主要有4 点:如果 当前线程池中得线程数目小于corepoolsize,则每来一个任务,就会创建一个线程去执行这个任务;如果 当前线程池中得线程数目>=corepoolsize,则每来一个任务, 会尝试将其添加到任务缓存队列当中,若添加成功, 则该任务会等待空闲线程将其取出去执行 ;若添加失败(一般来说就是任务缓存队列已满),则会尝试创建新得线程去执行这个任务;如果 当前线程池
46、中得线程数目达到maximumpoolsize,则会采取任务拒绝策略进行处理 ;如果线程池中得线程数量大于corepoolsize时,如果 某线程空闲时间超过keepalivetime, 线 程 将 被 终 止 , 直 至 线 程 池 中 得 线 程 数 目 不 大 于corepoolsize;如果允许为核心池中得线程设置存活时间,那么核心池中得线程空闲时间超过 keepalivetime,线程也会被终止。3. 线程池中得线程初始化默认情况下,创建线程池之后,线程池中就是没有线程得,需要提交任务之后才会创建线程。在实际中如果需要线程池创建之后立即创建线程,可以通过以下两个方法办到:presta
47、rtcorethread():初始化一个核心线程;prestartallcorethreads():初始化所有核心线程注意上面传进去得参数就是null ,如果传进去得参数为null ,则最后执行线程会阻塞在 gettask方法中得 workqueue、take();即等待任务队列中有任务。4. 任务缓存队列及排队策略在前面我们多次提到了任务缓存队列,即 workqueue,它用来存放等待执行得任务。workqueue 得类型为 blockingqueue<runnable>,通常可以取下面三种类型:arrayblockingqueue:基于数组得先进先出队列,此队列创建时必须指定大
48、小; linkedblockingqueue:基于链表得先进先出队列,如果创建时没有指定此队列大小,则默认为integer、max_valu;esynchronousqueue :这个队列比较特殊, 它不会保存提交得任务,而就是将直接新建一个线程来执行新来得任务。5. 任务拒绝策略当线程池得任务缓存队列已满并且线程池中得线程数目达到maximumpoolsize ,如果还有任务到来就会采取任务拒绝策略,通常有以下四种策略:threadpoolexecutor、abortpolicy:丢弃任务并抛出rejectedexecutionexception异常。threadpoolexecutor、d
49、iscardpolicy:也就是丢弃任务, 但就是不抛出异常。threadpoolexecutor、discardoldestpolicy:丢弃队列最前面得任务,然后 重新尝试执行任务(重复此过程)threadpoolexecutor、callerrunspolicy:由调用线程处理该任务6. 线程池得关闭threadpoolexecutor提供了两个方法,用于线程池得关闭,分别就是shutdown()与 shutdownnow() ,其中:shutdown():不会立即终止线程池,而就是要等所有任务缓存队列中得任务都执行完后才终止,但再也不会接受新得任务shutdownnow() :立即终止
50、线程池,并尝试打断正在执行得任务,并且清空任务缓存队列,返回尚未执行得任务7. 线程池容量得动态调整threadpoolexecutor提供了动态调整线程池容量大小得方法:setcorepoolsize()与 setmaximumpoolsize(),setcorepoolsize:设置核心池大小setmaximumpoolsize :设置线程池最大能创建得线程数目大小当上述参数从小变大时,threadpoolexecutor进行线程赋值,还可能立即创建新得线程来执行任务。主要就是 threadpoolexecutor得实现原理java 并发编程:线程池得使用1.3.10 线程池得几种方式ne
51、wfixedthreadpool(int nthreads)创建一个 固定长度得线程池 ,每当提交一个任务就创建一个线程, 直到 达到线程池得最大数量,这时线程规模将不再变化 ,当线程发生未预期得错误而结束时, 线程池会补充一个新得线程newcachedthreadpool()创建一个 可缓存得线程池 ,如果线程池得规模超过了处理需求, 将自动回收空闲线程 ,而当需求增加时,则可以自动添加新线程,线程池得规模不存在任何限制newsinglethreadexecutor()这就是一个单线程得executor ,它创建单个工作线程来执行任务,如果这个线程异常结束, 会创建一个新得来替代它;它得特点
52、就是能确保依照任务在队列中得顺序来串行执行newscheduledthreadpool(int corepoolsize)创建了一个固定长度得线程池,而且以延迟或定时得方式来执行任务,类似于timer 。参考:创建线程池得几种方式1.3.11 线程得生命周期新建 (new)、就绪( runnable )、运行( running )、阻塞 (blocked)与死亡 (dead)5 种状态(1) 生命周期得五种状态新建( new thread )当创建 thread 类得一个实例(对象)时,此线程进入新建状态(未被启动)。例如: thread t1=new thread();就绪( runnabl
53、e )线程已经被启动, 正在等待被分配给cpu时间片, 也就就是说此时线程正在就绪队列中排队等候得到 cpu资源。例如: t1 、start();运行( running )线程获得 cpu资源正在执行任务 (run()方法),此时除非此线程自动放弃cpu资源或者有优先级更高得线程进入,线程将一直运行到结束。死亡( dead)当线程执行完毕或被其它线程杀死,线程就进入死亡状态, 这时线程不可能再进入就绪状态等待执行。自然终止:正常运行run()方法后终止异常终止:调用 stop()方法让一个线程终止运行堵塞( blocked )由于某种原因导致正在运行得线程让出cpu并暂停自己得执行,即进入堵塞
54、状态。正在睡眠:用sleep(long t)方法可使线程进入睡眠方式。一个睡眠着得线程在指定得时间过去可进入就绪状态。正在等待:调用 wait()方法。(调用 motify()方法回到就绪状态)被另一个线程所阻塞:调用suspend() 方法。(调用 resume() 方法恢复) 参考:线程得生命周期1.4 锁机制1.4.1 说说线程安全问题线程安全就是指要控制多个线程对某个资源得有序访问或修改,而在这些线程之间没有产生冲突。在 java 里,线程安全一般体现在两个方面:1) 多个 thread对同一个 java实例得访问( read 与 modify )不会相互干扰,它主要体现在关键字 sy
55、nchronized。如 arraylist与 vector ,hashmap与 hashtable (后者每个方法前都有synchronized关键字)。如果您在 interator一个 list对象时,其它线程remove 一个 element ,问题就出现了。2) 每个线程都有自己得字段,而不会在多个线程之间共享。它主要体现在java 、lang 、threadlocal类,而没有 java 关键字支持,如像static、transient那样。1.4.2 volatile实现原理volatile就是轻量级得synchronized,它在多处理器开发中保证了共享变量得“可见 性”。可见性得意思就是当一个线程修改一个共享
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 《演讲与口才》课程教学大纲
- 2024年低钱饭店转让合同范本
- 2024年代理桶装水运输合同范本
- 2024年承接业务分包合同范本
- 企业培训教学大纲
- 医疗器械市场分析
- 2024公司生产经营承包合同
- 兽药合理使用培训
- 2024至2030年中国重型汽车空气滤清器行业投资前景及策略咨询研究报告
- 2024至2030年中国频率输入卡数据监测研究报告
- 2023-2024学年广东省深圳市南山区八年级(上)期末英语试卷
- 北京市丰台区2024-2025学年高二上学期11月期中考试生物试题 含解析
- 2024美团外卖服务合同范本
- 2023~2024学年第一学期高一期中考试数学试题含答案
- 非遗漆扇扇子科普宣传
- GB/T 15822.1-2024无损检测磁粉检测第1部分:总则
- MOOC 马克思主义民族理论与政策-广西民族大学 中国大学慕课答案
- 一种基于STM32的智能门锁系统的设计-毕业论文
- 烟草企业安全生产标准化 规范
- P91材质焊接及热处理工程作业指导书(完整版)
- 《海子诗人简介》PPT课件.ppt
评论
0/150
提交评论