1、 JavaSE 4java
1、 面向对象的特征有哪些方面 4mysql
2、 String是最基本的数据类型吗? 4程序员
3、 super()与this()的区别? 4web
4、 JAVA的事件委托机制和垃圾回收机制 4面试
5、 在JAVA中,如何跳出当前的多重嵌套循环? 4算法
6、 什么是java序列化,如何实现java序列化?(写一个实例) 4sql
7、 线程的基本概念、线程的基本状态以及状态之间的关系? 4编程
9、 什么是Java序列化,如何实现java序列化? 4小程序
10、 列举出JAVA 中6 个比较经常使用的包 4数组
11、 一个".java"源文件中是否能够包括多个类(不是内部类)?有什么限制? 5
12、 写几个线程安全类,不安全的,支持排序的类名? 5
13、 排序都有哪几种方法?请列举。用JAVA实现一个快速排序? 5
14、 什么是类的返射机制? 5
15、 类的返射机制中的包及核心类? 5
16、 获得Class的三个过程是什么? 5
17、 STOP()和SUSPEND()不推荐使用的缘由? 5
18、 静态变量和实例变量的区别? 6
19、 构造器的名能不能和类的名字相同? 6
20、 在一个主方法类可不能够调用一个非静态的方法? 6
21、 说一下垃圾回收的原理,能够直接从内存中回收吗? 6
22、 Java 的异常有哪几种,有什么区别? 6
23、 Integer 与int 的区别? 6
24、 Java Reflection 是什么? 6
25、 写几个java.lang.Object 类中的方法名称。 6
26、 数组有没有length()这个方法,String 有没有length()这个方法。 6
27、 Error 和exception 的区别与联系? 6
28、 静态的多态和动态的多态的区别? 6
29、 Collections 和Collection 的区别 6
30、 Class.forName 的做用?为何要用? 6
31、 Socket 如何获取本地ip 地址? 6
32、 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类 6
33、 char 型变量中能不能存贮一个中文汉字?为何? 6
34、 写clone()方法时,一般都有一行代码,是什么? 6
35、 说说经常使用集合类有哪些?有哪些方法? 6
36、 是否能够从一个static 方法内部发出对非static 方法的调用? 6
37、 Math.round(11.5)等於多少? Math.round(-11.5)等於多少? 6
38、 多线程有几种实现方法?同步有几种实现方法? 7
39、 内部类能够引用外部类的成员吗?有没有什么限制? 7
40、 Java 类实现序列化的方法(二种)?如在collection 框架中实现排序,要实现什么样的接口 7
41、 什么是Java 序列化,如何实现java 序列化?或者请解释Serializable 接口的做用。 7
42、 Java 中有几种类型的流?JDK 为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 7
43、 用JDBC 如何调用存储过程 7
44、 JAVA 事件有哪些模式? 7
45、 SOCKET 中有几中链接方式,各有什么区别? 7
46、 Hashtable 的原理 8
47、 JDBC 中的PreparedStatement 相比Statement 的好处? 8
48、 sleep()和wait()区别 8
49、 概述反射和序列化 8
50、 Java 中实现多态的机制是什么? 8
51、 abstract 的method 是否可同时是static, 是否可同时是native, 是否可同时是synchronized? 8
52、 如何唤起类中的一个方法? 8
53、 如何将数值型字符转换为数字(Integer,Double)? 8
54、 如何去小数点前两位,并四舍五入。 8
55、 int 和 Integer 有什么区别? 8
56、 String 和StringBuffer的区别? 9
57、 运行时异常与通常异常有何异同? 9
58、 说出ArrayList,Vector, LinkedList的存储性能和特性 9
59、 Collection 和 Collections的区别。 9
60、 &和&&的区别。 9
61、 HashMap和Hashtable的区别。 9
62、 Java包括哪些基本数据类型。 9
63、 什么是OOP?什么是类?请对比类和对象实例之间的关系 9
64、 JDK、JRE、JVM是什么? 9
65、 int和Integer有什么区别,互相之间如何转换 9
66、 类加载的初始化顺序 10
67、 final, finally, finalize的区别 10
68、 线程的基本概念、线程的基本状态以及状态之间的关系 10
69、 Overload(重载)和Overrided (重写)的区别。 10
70、 Overloaded的方法是否能够改变返回值的类型? 10
71、 abstract class和interface有什么区别? 10
72、 equals()和“==”的区别 10
73、 &和&&的区别。 11
74、 Java构造方法的特色 11
75、 Final能够修饰什么?修饰后具备什么特色 11
76、 接口是否可继承接口 11
77、 抽象类是否可实现(implements)接口? 11
78、 抽象类是否可继承实体类? 11
79、 String是最基本的数据类型吗? 11
80、 String s = new String(“abc”);建立了几个String Object? 11
81、 String、StringBuffer、StringBuilder的区别 11
82、 是否能够继承String类,为何 11
83、 GC是什么? 为何要有GC? 11
84、 异常的体系结构,从类与类之间的关系来回答 11
85、 JAVA语言如何进行异常处理,关键字:throws,throw,try,catch,finally分别表明什么意义? 12
86、 error和exception有什么区别 12
87、 常见的runtime exception有哪些 12
88、 数组有没有length()这个方法? String有没有length()这个方法? 12
89、 Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==仍是equals()? 它们有何区别? 12
90、 Java有没有goto 12
91、 swtich是否能做用在byte上,是否能做用在long上,是否能做用在String上? 12
92、 try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,何时被执行,在return前仍是后? 12
93、 Java有几种访问权限控制,请分别详细说明控制范围 12
94、 当一个对象被看成参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里究竟是值传递仍是引用传递? 13
95、 Equals()和hashCode()有什么关系? 13
96、 Java反射机制的原理 13
97、 @Retention的理解,自定义泛型 13
98、 可变参数的用法 13
9九、 abstract class和interface有什么区别? 13
100、 heap和stack有什么区别。 13
101、 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? 13
102、 请说出你所知道的线程同步的方法? 13
103、 char型变量中能不能存贮一个中文汉字?为何? 13
104、 如何取得年月日,小时分秒? 13
105、 如何取得从1970年到如今的毫秒数 14
106、 如何获取某个日期是当月的最后一天? 14
107、 如何格式化日期? 14
108、 编码转换,怎样实现将GB2312编码的字符串转换为ISO-8859-1编码的字符串。 14
109、 String s = new String("xyz");建立了几个String Object? 14
110、 float型float f=3.4是否正确? 14
111、 静态变量和实例变量的区别? 14
112、 是否能够从一个static方法内部发出对非static方法的调用? 15
113、 何时用assert? 15
2、 集合框架 15
114、 从接口、类的角度简述集合框架体系结构 15
115、 说出ArrayList,Vector, LinkedList的存储性能和特性 15
116、 Collection和Collections的区别,HashMap和Hashtable的区别 15
117、 List, Set, Map是否继承自Collection接口 15
118、 Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 15
119、 集合排序的常见二种写法? 16
120、 如何将数组转换成集合,集合转换成数组? 16
121、 如何对各类集合进行迭代? 16
122、 Entryset? 16
3、 IO流 16
123、 java中有几种类型的流? 16
124、 JDK为每种类型的流提供了一些抽象类以供继承,请说出他们分别是哪些类? 16
125、 字节流与字符流的转换方法? 16
126、 JavaIO流基础分类方式(字节流、字符流与基本流、过滤流)及他们之间的关系? 16
127、 什么是java序列化,如何实现java序列化? 16
4、 多线程 16
128、 多线程有几种实现方法? 16
129、 Thread和Runnable的区别和使用? 16
130、 如何实现线程同步? 16
131、 sleep() 和 wait() 有什么区别? 17
132、 同步和异步有何异同,在什么状况下分别使用他们?举例说明。 17
133、 如何启动一个线程? 517
134、 线程有哪些状态,这些状态是如何转换的? 17
5、 Socket 17
135、 TCP与UDP区别和使用 17
基本数据类型包括byte、int、char、long、float、double、boolean和short。 java.lang.String类是final类型的,所以不能够继承这个类、不能修改这个类。为了提升效率节省空间,咱们应该用StringBuffer类
This():当前类的对象,super父类对象。
Super():在子类访问父类的成员和行为,必须受类继承规则的约束
而this他表明当前对象,固然全部的资源均可以访问.
在构造函数中,若是第一行没有写super(),编译器会自动插入.可是若是父类没有不带参数的构造函数,或这个函数被私有化了(用private修饰).此时你必须加入对父类的实例化构造.而this就没有这个要求,由于它自己就进行实例化的构造.
而在方法中super和this使用的方法就差很少了.只不过super 要考虑是否能访问其父类的资源.
java 事件委托机制的概念,一个源产生一个事件并将它送到一个或多个监听器那里。在这种方案中,监听器简单的等待,直到它收到一个事件。一旦事件被接受,监听器将处理这个事件,而后返回。
垃圾回收机制 垃圾收集是将分配给对象但再也不使用的内存回收或释放的过程。若是一个对象没有指向它的引用或者其赋值为null,则次对象适合进行垃圾回收
用break; return 方法。
序列化:
能够将一个对象保存到一个文件,因此能够经过流的方式在网络上传输,能够将文件的内容读取,转化为一个对象。
处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时所引起的问题。
序列化的实现:
将须要被序列化的类实现Serializable接口,该接口没有须要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,而后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就能够将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
线程的基本概念:线程指在程序执行过程当中,可以执行程序代码的一个执行单位,每一个程序至少都有一个线程,也就是程序自己。
Java中的线程有四种状态分别是:运行、就绪、挂起、结束。
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时所引起的问题。
序列化的实现:将须要被序列化的类实现Serializable接口,该接口没有须要实现的方法,implements Serializable只是为了标注该对象是可被序列化的,而后使用一个输出流(如:FileOutputStream)来构造一个ObjectOutputStream(对象流)对象,接着,使用ObjectOutputStream对象的writeObject(Object obj)方法就能够将参数为obj的对象写出(即保存其状态),要恢复的话则用输入流。
java.lang;java.util;java.io;java.sql;java.awt;java.net;javax.swing
能够。若是这个类的修饰符是public,其类名与文件名必须相同。
线程安全类:Vector 、Hashtable、Stack。
线程不安全的类:ArrayList、Linkedlist、HashSet、TreeSet、HashMap、TreeMap等。
支持排序的类有HashSet、LinkedHashSet、TreeSet 等(Set 接口下的实现都支持排序)
排序的方法有:插入排序(直接插入排序、希尔排序),交换排序(冒泡排序、快速排序),选择排序(直接选择排序、堆排序),归并排序,分配排序(箱排序、基数排序)
快速排序的伪代码。
动态得到对象
经过类(Class对象),能够得出当前类的fields、method、construtor、interface、superClass、modified等,同是能够经过类实例化一个实例、设置属性、唤醒方法。Spring中一切都是返射、struts、hibernate都是经过类的返射进行开发的。
java.lang.Class
java.lang.refrection.Method
java.lang.refrection.Field
java.lang.refrection.Constructor
java.lang.refrection.Modifier
java.lang.refrection.Interface
对象.getClass()
类.class或Integer.type(int) Integer.class(java.lang.Integer)
Class.forName();
stop()是由于它不安全。它会解除由线程获取的全部锁定,当在一个线程对象上调用stop()方法时,这个线程对象所运行的线程就会当即中止,假如一个线程正在执行:synchronized void { x = 3; y = 4;} 因为方法是同步的,多个线程访问时总能保证x,y 被同时赋值,而若是一个线程正在执行到x = 3;时,被调用了stop()方法,即便在同步块中,它也干脆地stop 了,这样就产生了不完整的残废数据。而多线程编程中最最基础的条件要保证数据的完整性,因此请忘记线程的stop 方法,之后咱们不再要说“中止线程”了。并且若是对象处于一种不连
贯状态,那么其余线程能在那种状态下检查和修改它们。suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这以前得到的锁定。此时,其余任何线程都不能访问锁定的资源,除非被"挂起"的线程恢复运行。对任何线程来讲,若是它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会形成死锁。因此不该该使用suspend(),而应在本身的Thread 类中置入一个标志,指出线程应该活动仍是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()从新启动线程。
静态变量属于类,不用实例化就已经存在,全部的实例共享同一个静态变量,能够经过类名和实例名来访问。实例变量属于实例,每一个实例都有本身的这个变量,只能经过实例名来访问。
方法名必须和类名相同,无返回值,不能显示被调用,实例化时自动调用。完成初始化工做。系统会默认提供了一个默认的无参构造器。初始化子类时,会先调用父类的构造器,能够在方法中经过supper()指定调用父类的哪个构造器。
若是在同一个类中,实例方法能够直接使用方法名调用,静态方法不能直接调用非静态方法,须要实例化后,经过对象再调用。
若是在不一样类中,实例方法须要先实例化,而后经过对象调用,静态方法,直接经过类名.方法调用。
对于GC来讲,当程序员建立对象时,GC就开始监控这个对象的地址、大小以及使用状况。一般,GC采用有向图的方式记录和管理堆(heap)中的全部对象。经过这种方式肯定哪些对象是"可达的",哪些对象是"不可达的"。当GC肯定一些对象为"不可达"时,GC就有责任回收这些内存空间。能够。程序员能够手动执行System.gc(),通知GC运行,可是Java语言规范并不保证GC必定会执行。
异常是指java程序运行时(非编译)所发生的非正常状况或错误,与现实生活中的事件很类似,现实生活中的事件能够包含事件发生的时间、地点、人物、情节等信息,能够用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每一个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。
Java对异常进行了分类,不一样类型的异常分别用不一样的Java类表示,全部异常的根类为java.lang.Throwable,Throwable下面又派生了两个子类:Error和Exception,Error表示应用程序自己没法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序还可以克服和恢复的问题,其中又分为系统异常和普通异常,系统异常是软件自己缺陷所致使的问题,也就是软件开发人员考虑不周所致使的问题,软件使用者没法克服和恢复这种问题,但在这种问题下还可让软件系统继续运行或者让软件死掉,例如,数组脚本越界(ArrayIndexOutOfBoundsException),空指针异常(NullPointerException)、类转换异常(ClassCastException);普通异常是运行环境的变化或异常所致使的问题,是用户可以克服的问题,例如,网络断线,硬盘空间不够,发生这样的异常后,程序不该该死掉。
java为系统异常和普通异常提供了不一样的解决方案,编译器强制普通异常必须try..catch处理或用throws声明继续抛给上层调用方法处理,因此普通异常也称为checked异常,而系统异常能够处理也能够不处理,因此,编译器不强制用try..catch处理或用throws声明,因此系统异常也称为unchecked异常。
int是java提供的8种原始数据类型之一。Java为每一个原始类型提供了封装类,Integer是java为int提供的封装类。int的默认值为0,而Integer的默认值为null,即Integer能够区分出未赋值和值为0的区别,int则没法表达出未赋值的状况,例如,要想表达出没有参加考试和考试成绩为0的区别,则只能使用Integer。在JSP开发中,Integer的默认为null,因此用el表达式在文本框中显示时,值为空白字符串,而int默认的默认值为0,因此用el表达式在文本框中显示时,结果为0,因此,int不适合做为web层的表单数据的类型。
在Hibernate中,若是将OID定义为Integer类型,那么Hibernate就能够根据其值是否为null而判断一个对象是不是临时的,若是将OID定义为了int类型,还须要在hbm映射文件中设置其unsaved-value属性为0。
另外,Integer提供了多个与整数相关的操做方法,例如,将一个字符串转换成整数,Integer中还定义了表示整数的最大值和最小值的常量。
reflection反射,
1.Java 反射机制主要提供了如下功能:
在运行时判断任意一个对象所属的类。
在运行时构造任意一个类的对象。
在运行时判断任意一个类所具备的成员变量和方法。
在运行时调用任意一个对象的方法
2、Reflection 是Java被视为动态(或准动态)语言的一个关键性质。这个机制容许程序在运行时透过Reflection APIs取得任何一个已知名称的class的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Serializable),也包括fields和methods的全部信息,并可于运行时改变fields内容或调用methods
尽管Java不是动态语言,它却有着一个很是突出的动态相关机制:Reflection。这个字的意思是“反射、映象、倒影”,用在Java身上指的是咱们能够于运行时加载、探知、使用编译期间彻底未知的classes。换句话说,Java程序能够加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、检讨)。Reflection和introspection是常被并提的两个术语
java中,不管生成某个类的多少个对象(实例),这些对象都会对应同一个Class对象。
3、在JDK中,主要由如下类来实现Java反射机制,这些类都位于java.lang.reflect包中
–Class类:表明一个类(这个类很特殊,位于java.lang包下)。
–Field 类:表明类的成员变量(成员变量也称为类的属性)。
–Method类:表明类的方法。
–Constructor 类:表明类的构造方法。
–Array类:提供了动态建立数组,以及访问数组的元素的静态方法
Object():默认构造方法
clone():建立并返回此对象的一个副本。
equals(Object obj):指示某个其余对象是否与此对象“相等”。
finalize():当垃圾回收器肯定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
getClass():返回一个对象的运行时类。
hashCode():返回该对象的哈希码值。
notify():唤醒在此对象监视器上等待的单个线程。
notifyAll():唤醒在此对象监视器上等待的全部线程。
toString():返回该对象的字符串表示。
wait():致使当前的线程等待,直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法。
wait(long timeout):致使当前的线程等待,直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
wait(long timeout, int nanos):致使当前的线程等待,直到其余线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其余某个线程中断当前线程,或者已超过某个实际时间量。
数组没有length()方法,String有length()方法。
1.Throwable 类是 Java 语言中全部错误或异常的超类。它的两个子类是Error和Exception;
2.Error 是 Throwable 的子类,用于指示合理的应用程序不该该试图捕获的严重问题。大多数这样的错误都是异常条件。虽然 ThreadDeath 错误是一个“正规”的条件,但它也是 Error 的子类,由于大多数应用程序都不该该试图捕获它。在执行该方法期间,无需在其 throws 子句中声明可能抛出可是未能捕获的 Error 的任何子类,由于这些错误多是不再会发生的异常条件。
3.Exception 类及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件。
4.RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。可能在执行方法期间抛出但未被捕获的RuntimeException 的任何子类都无需在 throws 子句中进行声明。它是Exception的子类。
Error的继承关系:java.lang.Object -> java.lang.Throwable -> java.lang.Error
Exception的继承关系:java.lang.Object -> java.lang.Throwable -> java.lang.Error
Exception:
1.能够是可被控制(checked) 或不可控制的(unchecked)
2.表示一个由程序员致使的错误
3.应该在应用程序级被处理
Error:
1.老是不可控制的(unchecked)
2.常常用来用于表示系统错误或低层资源的错误
3.如何可能的话,应该在系统级被捕捉
静态多态性指的是程序在编译时,系统就能决定调用哪一个函数,如重载。
动态多态性指在运行中才能动态肯定操做指针所指的对象,主要经过虚函数和重写来实现。
java 的多态机制遵循一个原则:当父类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,可是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法
概念理解起来有点抽象。仍是看个例子吧。
静态多态性:
add(int a);
add(int a,int b);
add(double a);
add(double a,double b);
动态多态性
public class A{ }
public class AB extends A{ }
public class AC extends A{ }
java.util.Collection 是一个集合接口。它提供了对集合对象进行基本操做的通用接口方法。Collection接口在Java 类库中有不少具体的实现。Collection接口的意义是为各类具体的集合提供了最大化的统一操做方式。
java.util.Collections 是一个包装类。它包含有各类有关集合操做的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。
Class.forName : 返回与给定的字符串名称相关联 类 或 接口 的Class对象。
至于何时用,能够考虑一下这个问题,给你一个字符串变量,它表明一个类的包名和类名,你怎么实例化它?
A a = (A)Class.forName( "pacage.A" ).newInstance();这和 A a =new A();是同样的效果。
jvm在装载类时会执行类的静态代码段,要记住静态代码是和class绑定的,class装载成功就表示执行了你的静态代码了,并且之后不会再执行这段静态代码了。
Class.forName(xxx.xx.xx)的做用是要求JVM查找并加载指定的类,也就是说JVM会执行该类的静态代码段。
动态加载和建立Class 对象,好比想根据用户输入的字符串来建立对象
java中从Socket中获取IP地址经过Socket的getInetAddress()方法便可得到Socket中的Ip地址。其中Socket中还能够经过getLocalAddress()获取Socket绑定的本地地址。
接口能够继承接口。抽象类能够实现(implements)接口,抽象类是能够继承具体类。抽象类中能够有静态的main方法。
记住抽象类与普通类的惟一区别就是不能建立实例对象和容许有abstract方法。
没法存储。由于char型具备的空间比汉字占有的空间要小。char型变量,占用空间为一个字节。汉字根据不一样编码方式,最少须要两个字节,最多可能有三个字节甚至6个字节。因此单个char变量是没法存储下中文汉字的。
Clone 有缺省行为,super.clone();他负责产生正确大小的空间,并逐位复制
一般咱们使用的集合类都大可能是由List、Set、Map 这三类接口派生出来的类,例如:ArrayList、Vector、LinkedList、Stack、TreeSet、Hashtable、HashMap 等集合类的大部分方法都是由Collection 接口定义的,主要包括有:add(E e)、remove(Object e)、addAll(),remove()、contains(Object obj)、clear()等。
不能够。由于非static 方法是要与对象关联在一块儿的,必须建立一个对象后,才能够在该对象上进行方法调用,而static 方法调用时不须要建立对象,能够直接调用。
Math 类中提供了三个与取整有关的方法:ceil、floor、round,这些方法的做用与它们的英文名称的含义相对应,例如,ceil 的英文意义是天花板,该方法就表示向上取整,因此,Math.ceil(11.3)的结果为12,Math.ceil(-11.3)的结果是-11;floor 的英文意义是
地板,该方法就表示向下取整,因此,Math.floor(11.6)的结果为11,Math.floor(-11.6)的结果是-12;最难掌握的是round 方法,它表示“四舍五入”,算法为Math.floor(x+0.5),即将原来的数字加上0.5 后再向下取整, 因此, Math.round(11.5) 的结果为12 ,
Math.round(-11.5)的结果为-11。
多线程有两种实现方法,分别是继承Thread 类与实现Runnable 接口。同步的实现方面有两种,分别是synchronized,wait 与notify 。
a. wait():使一个线程处于等待状态,而且释放所持有的对象的lock。
b. sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException 异常。
c. notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM 肯定唤醒哪一个线程,并且不是按优先级。
d. allnotity():唤醒全部处入等待状态的线程,注意并非给全部唤醒线程一个对象的锁,而是让它们竞争。
彻底能够。若是不是静态内部类,那没有什么限制!若是你把静态嵌套类看成内部类的一种特例,那在这种状况下不能够访问外部类的普通
成员变量,而只能访问外部类中的静态成员。
java.io.Serializable 接口或实现Externalizable 接口。
Collection 框架中实现比较要实现Comparable 接口或Comparator 接口,并实现比较方法
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时所引起的问题。序列化的实现:将须要被序列化的类实现Serializable 接口,该接口没有须要实现的方法,implements Serializable 只是为了标注该对象是可被序列化的,而后使用一个输出流( 如: FileOutputStream) 来构造一个ObjectOutputStream( 对象流) 对象, 使用ObjectOutputStream 对象的writeObject(Object obj)方法就能够将参数为obj 的对象写出,
那么在另外一端,经过ObjectInputStream 对象的readObject(Object obj)获取到字节流数据后,要将字节流转换成原对象,这叫反序列化,以便将数据存储在文件中或在网络传输。Serializable 接口描述启用其序列化功能,未实现此接口的类将没法使其任何状态序列化或反序列化。Serializable 接口没有方法或字段,仅用于标识可序列化的语义,标识实现了该接口的对象属性可被序列化
字节流,字符流两种类型流。字节流继承于InputStream、OutputStream;字符流继承于Reader、Writer。其它与IO 操做相关的类都是派生至上述4 个抽象类,如字节相关的:FileInputStream、FileOutputStream 类;字符相关的:BufferedReader、Buffered Writer类
经过JDBC组件中的CallableStatement接口实现调用存储过程。
核心代码以下: Class.forName("com.mysql.jdbc.Driver");
Connection conn= DriverManager.getConnection("jdbc:mysql:///test","root","root"); CallableStatement cstmt = cn.prepareCall("{call insert_Student(?,?,?)}"); cstmt.registerOutParameter(3,Types.INTEGER);
cstmt.setString(1, "wangwu");
cstmt.setInt(2, 25); cstmt.execute();
一、事件直接驱动模式。它的特色是直接并且快,是必须常用的,主要适合于迅速处理前台的命令,一般就是咱们说的command(命令)模式。
2.监控式事件模式。主要借助第三者来监控和触发事件,就是一般咱们说的观察者模式。特色是: 有一个观察者置身事外在按期独立运行着,咱们将咱们要监听的事件向这个观察者注册,这样观察者就代替咱们来监听这个事件,应用客户端经过观察者来得到事件情况。
Sockets 有两种主要的操做方式:面向链接(TCP/IP)的和无链接(UDP)的。无链接的操做使用数据报协议,无链接的操做是快速的和高效的,可是数据安全性不佳. 面向链接的操做使用TCP 协议.面向链接的操做比无链接的操做效率更低,可是数据的安全性更高
经过节点的关键码肯定节点的存储位置,即给定节点的关键码k,经过必定的函数关系H(散列函数),获得函数值H(k),将此值解释为该节点的存储地址
预编译语句java.sql. ,扩展自Statement,不但具备Statement的全部能力并且具备更强大的功能。不一样的是,PreparedStatement 是在建立语句对象的同时给出要执行的sql 语句。这样,sql 语句就会被系统进行预编译,执行的速度会有所增长,
尤为是在执行大语句的时候,效果更加理想
sleep() 方法:线程主动放弃CPU,使得线程在指定的时间内进入阻塞状态,不能获得CPU 时间,指定的时间一过,线程从新进入可执行状态。典型地,sleep() 被用在等待某个资源就绪的情形:测试发现条件不知足后,让线程阻塞一段时间后从新测
试,直到条件知足为止。
wait( ) :与notify()配套使用,wait()使得线程进入阻塞状态,它有两种形式,一种容许指定以毫秒为单位的一段时间做为参数,另外一种没有参数,当指定时间参数时对应的notify() 被调用或者超出指定时间时线程从新进入可执行状态,后者则必须对应的notify() 被调用
Reflection:是Java 被视为动态语言的一个关键性质。这个机制容许程序在运行时透过Reflection APIs 取得任何一个已知名称的class 的内部信息,包括其modifiers(诸如public, static 等等)、superclass(例如Object)、实现之interfaces(例如Cloneable),也包括fields 和methods 的全部信息,并可于运行时改变fields 内容或唤起methods。序列化:就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。能够对流化后的对象进行读写操做,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操做时的问题。
重写,重载
方法的重写Overriding 和重载Overloading 是Java 多态性的不一样表现。重写Overriding 是父类与子类之间多态性的一种表现,重载Overloading 是一个类中多态性的一种表现。若是在子类中定义某方法与其父类有相同的名称和参数,咱们说该方法被重写(Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。果在一个类中定义了多个同名的方法,它们或有不一样的参数个数或有不一样的参数类型,则称为方法的重载(Overloading)。Overloaded 的方法是能够改变返回值的类型。
abstract的method 不能够是static的,由于抽象的方法是要被子类实现的native方法表示该方法要用另一种依赖平台的编程语言实现的,不存在着被子类实现的问题,因此,它也不能是抽象的,不能与abstract混用;
关于synchronized与abstract合用的问题,我以为也不行,由于在我几年的学习和开发中,历来没见到过这种状况,而且我以为synchronized应该是做用在一个具体的方法上才有意义。并且,方法上的synchronized同步所使用的同步锁对象是this,而抽象方法上没法肯定this是什么。
产生一个Class数组,说明方法的参数
经过Class对象及方法参数获得Method
经过method.invoke(实例,参数值数组)唤醒方法
Integer.parseInt(“1234”)
Double.parseDouble(“123.2”)
double d=1256.22d;
d=d/100;
System.out.println(Math.round(d)*100);
Java 提供两种不一样的类型:引用类型和原始类型(或内置类型)。Int是java的原始数据类型,Integer是java为int提供的封装类。Java为每一个原始类型提供了封装类。 原始类型封装类booleanBoolean charCharacter byteByte shortShort intInteger longLong floatFloat doubleDouble 引用类型和原始类型的行为彻底不一样,而且它们具备不一样的语义。引用类型和原始类型具备不一样的特征和用法,它们包括:大小和速度问题,这种类型以哪一种类型的数据结构存储,当引用类型和原始类型用做某个类的实例数据时所指定的缺省值。对象引用实例变量的缺省值为 null,而原始类型实例变量的缺省值与它们的类型有关。
JAVA平台提供了两个类:String和StringBuffer,它们能够储存和操做字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可使用StringBuffer。典型地,你可使用StringBuffers来动态构造字符数据。
异常表示程序运行过程当中可能出现的非正常状态,运行时异常表示虚拟机的一般操做中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,可是并不要求必须声明抛出未被捕获的运行时异常。
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增长和插入元素,它们都容许直接按序号索引元素,可是插入元素要涉及数组元素移动等内存操做,因此索引数据快而插入数据慢,Vector因为使用了synchronized方法(线程安全),一般性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据须要进行前向或后向遍历,可是插入数据时只须要记录本项的先后项便可,因此插入速度较快。
Collection是集合类的上级接口,继承与他的接口主要有Set 和List。Collections是针对集合类的一个帮助类,他提供一系列静态方法实现对各类集合的搜索、排序、线程安全化等操做。
&是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap容许空(null)键值(key),因为非线程安全,效率上可能高于Hashtable。
HashMap容许将null做为一个entry的key或者value,而Hashtable不容许。
HashMap把Hashtable的contains方法去掉了,改为containsvalue和containsKey。由于contains方法容易让人引发误解。 Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不一样是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不须要本身为它的方法实现同步,而HashMap 就必须为之提供外同步。 Hashtable和HashMap采用的hash/rehash算法都大概同样,因此性能不会有很大的差别。
byte int short long float double char boolean
面向对象编程;
类是具备相同属性和行为的对象的结合;
对象是某个类的一个实例,类有0或多个对象;
java开发包,java运行环境,java虚拟机
int是基本数据类型,Integer是封装类;
int无默认值,Integer默认值为0。
Integer a = new Integer(1);
int b = a.intValue();
父类--静态变量
父类--静态初始化块
子类--静态变量
子类--静态初始化块
父类--变量
父类--初始化块
父类--构造器
子类--变量
子类--初始化块
子类--构造器
final修饰属性、方法、类:属性不可改变、方法不可重写、类不可继承;
finally在异常处理时进行清除操做,无论是否捕捉到异常,finaly块中的代码都会执行;
finalize方法是在垃圾收集器删除对象以前对这个对象调用的。
一个程序中能够有多条执行线索同时执行,一个线程就是程序中的一条执行线索,每一个线程上都关联有要执行的代码,便可以有多段程序代码同时运行,每一个程序至少都有一个线程,即main 方法执行的那个线程。若是只是一个cpu,它怎么可以同时执行多段程序呢?这是从宏观上来看的,cpu 一会执行a 线索,一会执行b 线索,切换时间很快,给人的感受是a,b 在同时执行,比如你们在同一个办公室上网,只有一条连接到外部网线,其实,这条网线一会为a 传数据,一会为b 传数据,因为切换时间很短暂,因此,你们感受都在同时上网。状态:就绪,运行,synchronize 阻塞,wait 和sleep 挂起,结束。wait 必须在synchronized内部调用。调用线程的start 方法后线程进入就绪状态,线程调度系统将就绪状态的线程转为运行状态,遇到synchronized 语句时,由运行状态转为阻塞,当synchronized 得到锁后,由阻塞转为运行,在这种状况能够调用wait 方法转为挂起状态,当线程关联的代码执行完后,线程变为结束状态。
多态性的不一样体现
重载:同一个类中,方法名相同,参数不一样
重写:父子类中,方法名相同、参数相同、返回值类型原则上要求相同,但子类的方法权限不容许小于父类,不容许抛出比父类更多的异常。
|
位置 |
方法名 |
参数表 |
返回值 |
访问修饰符 |
方法重写 |
子类 |
相同 |
相同 |
相同或是其子类 |
不能比父类更严格 |
方法重载 |
同类 |
相同 |
不相同 |
无关 |
无关 |
能够
声明方法的存在而不去实现它的类叫抽象类。不能建立抽象类的实例;然而能够建立安一个变量,其类型是一个抽象类,并让他指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。
接口是抽象类的变体,接口中全部方法都是抽象的。多继承性可经过实现这样的接口而得到。接口只能够定义static final成员变量
==比较地址,equals比较内容,equals为true,== 不必定为true
&是位运算符,按位与 &&是逻辑运算符,逻辑与
没有返回值、方法名与类名相同、不能由编程人员调用、能够定义多个构造方法,若是没有,编译时系统会自动插入一个无参构造方法,这个构造方法不执行任何代码、能够重载。
变量:常量,只能被赋值一次,值不可改变
方法:不可重写
类:不可继承,没有子类
能够
能够
能够继承,可是和实体类的继承同样,也要求父类可继承,而且拥有子类可访问到的构造器。
不是,它是final类型的。
2个,一个是String对象池中的“xyz”,一个是堆中的对象,指向池中的“xyz”至于s,是放在栈中的引用,不是对象。
String是不可变的对象,每次对String类型进行改变的时候实际上是产生了一个新的String对象,而后指针指向新的String对象;
StringBuffer是线程安全的可变字符序列,须要同步,则使用。
StringBuilder线程不安全,速度更快,单线程使用。
(String是一个类,但倒是不可变的,因此String建立的算是一个字符串常量,StringBuffer和StringBuilder都是可变的。因此每次修改String对象的值都是新建一个对象再指向这个对象。而使用StringBuffer则是对StringBuffer对象自己进行操做。因此在字符串常常改变的状况下,使用StringBuffer要快得多。)
不能够,string类是final的
经过System.gc runtime.gc , finllize (都在java.lang包下)这两个方法来执行
java垃圾回收器,Java是由C++发展来的。它摈弃了C++中一些繁琐容易出错的东西。其中有一条就是这个GC。
GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问题的地方,忘记或者错误的内存回收会致使程序或系统的不稳定甚至崩溃,Java提供的GC功能能够自动监测对象是否超过做用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操做方法。
java.lang.Throwable
Error和Exception
RuntimeException和非运行时异常,非运行时异常须要处理。
Try:执行部分,产生异常
Catch:捕捉异常
Finally:无论有没有异常都执行
Throws:在方法声明处声明要抛出的异常,调用者必须对其进行处理。
Throw:抛出一个异常
在try中能够抛出异常,通常与声明的异常相同。
自定义异常要继承于Exception或Exception的子类
error是错误,程序基本无能为力。exception是由于程序设计的瑕疵而引发的问题或者通常性问题,是程序必须处理的。
ClassCastExcetion,NullPointerException,NumberFormatException,OutOfMemoryException,ArrayIndexOfBoundsExceptionArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException,CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException, ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException
非运行时异常:IO异常、SQL异常、NoSuchMethod异常
数组没有length()这个方法,有length的属性。String有有length()这个方法。
Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
goto是java保留字,但没有实现;可是有label
switch(expr1)中,expr1是一个整数表达式。所以传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能做用于swtich。
会执行,在return前执行
访问修饰符 |
本类 |
同包 |
子类 |
其余 |
private |
√ |
|
|
|
默认(friendly) |
√ |
√ |
|
|
protected |
√ |
√ |
√ |
|
public |
√ |
√ |
√ |
√ |
答:是值传递。Java 编程语言只有值传递参数。当一个对象实例做为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容能够在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
equals()相等的两个对象,hashcode()必定相等; equals()不相等的两个对象, hashcode()有可能相等。
核心就是这个方法, 把参数is理解成一个数组就是了:
private static void function(int... is) {
for (int i = 0; i < is.length; i++) {
System.out.print(is[i]+" ");
}
}
声明方法的存在而不去实现它的类被叫作抽象类(abstract class),它用于要建立一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的状况。不能建立abstract 类的实例。然而能够建立一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的全部抽象方法提供实现,不然它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类能够在类中实现这些方法。接口(interface)是抽象类的变体。在接口中,全部方法都是抽象的。多继承性可经过实现这样的接口而得到。接口中的 全部方法都是抽象的,没有一个有程序体。接口只能够定义static final成员变量。接口的实现与子类类似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)全部这种接口的方法。而后,它能够在实现了该接口的类的任何对象上调用接口的方法。因为有抽象类,它容许使用接口名做为引用变量的类型。一般的动态联编将生效。引用能够转换到接口类型或从接口类型转换,instanceof 运算符能够用来决定某对象的类是否实现了接口
栈是一种线形集合,其添加和删除元素的操做应在同一段完成。栈按照后进先出的方式进行处理。堆是栈的一个组成元素
不能,一个对象的一个synchronized方法只能由一个线程访问。
wait():使一个线程处于等待状态,而且释放所持有的对象的lock。sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException异常。notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM肯定唤醒哪一个线程,并且不是按优先级。Allnotity():唤醒全部处入等待状态的线程,注意并非给全部唤醒线程一个对象的锁,而是让它们竞争。
可以定义成为一个中文的,由于java中以unicode编码,一个char占16个字节,因此放一个中文是没问题的
Calendar c=Calendar.getInstance();
c.set(Calendar.YEAR,2004);
c.set(Calendar.MONTH,0);
c.set(Calendar.DAY_OF_MONTH,31);
System.out.println(c.get(Calendar.YEAR)+" "+(c.get(Calendar.MONTH)+1)+" "+c.get(Calendar.DAY_OF_MONTH));
Java.util.Date dat=new Date();
long now=dat.getTime();
当前日期加一天,若当前日期与结果的月份不相同,就是最后一天。
取下一个月的第一天,下一个月的第一天-1
public static void main(String[] args) {
Calendar c=Calendar.getInstance();
c.set(Calendar.YEAR,2004);
c.set(Calendar.MONTH,0);
c.set(Calendar.DAY_OF_MONTH,30);
Calendar c1=(Calendar)c.clone();
System.out.println(c.get(Calendar.YEAR)+" "+(c.get(Calendar.MONTH)+1)+" "+c.get(Calendar.DAY_OF_MONTH));
c.add(Calendar.DAY_OF_MONTH,1);
if(c.get(Calendar.MONTH)!=c1.get(Calendar.MONTH)) {
System.out.println("是最后一天");
}else {
System.out.println("不是取后一天");
}
}
Import java.text. SimpleDateFormat;
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date dat=new Date();
//把日期转化为字符串
String str=sdf.format(dat);
System.out.println(str);
//将字符串转化为日期
Java.util.Date d1=sdf.parse(“yyyy-mm-dd”);
String a=new String("中".getBytes("gb2312"),"iso-8859-1");
String a=new String("中".getBytes("iso-8859-1"));
New了一个,”XYZ”原本又是一个,两个。
报错,应当是float f=3.4f
若是是float f=3(整数)正确
static i = 10; //常量
class A a; a.i =10;//可变
静态方法能够调用静态变量。
实现方法能够调用静态变量、实例变量
不能够,若是其中包含对象的method();不能保证对象初始化。
assertion (断言)在软件开发中是一种经常使用的调试方式,不少开发语言中都支持这种机制。在实现中,assertion就是在程序中的一条语句,它对一个 boolean表达式进行检查,一个正确程序必须保证这个boolean表达式的值为true;若是该值为false,说明程序已经处于不正确的状态下,系统将给出警告或退出。通常来讲,assertion用于保证程序最基本、关键的正确性。assertion检查一般在开发和测试时开启。为了提升性能,在软件发布后,assertion检查一般是关闭的。
ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增长和插入元素,它们都容许直接按序号索引元素,可是插入元素要涉及数组元素移动等内存操做,因此索引数据快而插入数据慢,Vector因为使用了synchronized方法(线程安全),一般性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据须要进行前向或后向遍历,可是插入数据时只须要记录本项的先后项便可,因此插入速度较快。
Collection是集合类的上级接口,继承于它的借口主要有Set和List;
Collections是针对集合类的一个帮助类,他提供了一系列静态方法实现对各类集合的搜索、排序、线程安全化等操做;
HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap容许空(null)键值(key),因为非线程安全,效率上可能高于Hashtable。
HashMap容许将null做为一个entry的key或者value,而Hashtable不容许。
HashMap把Hashtable的contains方法去掉了,改为containsvalue和containsKey。由于contains方法容易让人引发误解。 Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
最大的不一样是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不须要本身为它的方法实现同步,而HashMap 就必须为之提供额外同步。
Hashtable和HashMap采用的hash/rehash算法都大概同样,因此性能不会有很大的差别。
Ps: 集合的帮助类是java.util.Collections
数组的帮助类是 arrays;
List、Set是,Map不是;
Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。
在“集合框架”中有两种比较接口:Comparable接口和Comparator接口。像String和Integer等Java内建类实现Comparable接口以提供必定排序方式,但这样只能实现该接口一次。对于那些没有实现Comparable接口的类、或者自定义的类,您能够经过Comparator接口来定义您本身的比较方式。
数组转集合:List list = Arrays.asList(new String[]{“abc”,”abc”});
集合转数组:toArray()
List:add()、get()、for();
Set:add()、经过Iterator取、iterator();
Map:put()、经过keySet()、entrySet()迭代
entrySet比keySet更快
字符流、字节流;
输入流、输出流;
InputStream、OutputStream、Reader、Writer
InputStreamReader OutputStreamWriter
实现序列化接口Serializable;ObjectOutputStream、ObjectInputStram
实现Runnable接口,实现run方法,new Thread(对象).start();继承Thread类,new一个对象,对象.start()启动。
Thread类的start不能覆盖;Runnable的run方法由Thread的start调用
synchronized:在同一时刻,只能被一个线程访问。要求对象先持有对象上的锁。代码执行完会自动释放锁。
wait(),notify()
sleep是线程类(Thread)的方法,致使此线程暂停执行指定时间,给执行机会给其余线程,可是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。wait是Object类的方法,对此对象调用wait方法致使本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备得到对象锁进入运行状态。
若是数据将在线程间共享。例如正在写的数据之后可能被另外一个线程读到,或者正在读的数据可能已经被另外一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。当应用程序在对象上调用了一个须要花费很长时间来执行的方法,而且不但愿让程序等待方法的返回时, 就应该使用异步编程,在不少状况下采用异步途径每每更有效率。
start方法
建立状态:new Thread
可运行状态:Runnable,start方法启动线程后,分配了除cpu外的其余资源yield方法后,IO完成、join中断、sleep借宿、同步锁被释放
运行中状态:Running,占有cpu,系统真正执行run方法
阻塞状态:Blocked,sleep方法、join方法、wait方法,synchronized进入同步块后
死亡状态:Dead,run运行结束或者异常退出
一个进程是一个独立(self contained)的运行环境,它能够被看做一个程序或者一个应用。而线程是在进程中执行的一个任务。Java运行环境是一个包含了不一样的类和程序的单一进程。线程能够被称为轻量级进程。线程须要较少的资源来建立和驻留在进程中,而且能够共享进程中的资源。
在多线程程序中,多个线程被并发的执行以提升程序的效率,CPU不会由于某个线程须要等待资源而进入空闲状态。多个线程共享堆内存(heap memory),所以建立多个线程去执行一些任务会比建立多个进程更好。举个例子,Servlets比CGI更好,是由于Servlets支持多线程而CGI不支持。
当咱们在Java程序中建立一个线程,它就被称为用户线程。一个守护线程是在后台执行而且不会阻止JVM终止的线程。当没有用户线程在运行的时候,JVM关闭程序而且退出。一个守护线程建立的子线程依然是守护线程。
有两种建立线程的方法:一是实现Runnable接口,而后将它传递给Thread的构造函数,建立一个Thread对象;二是直接继承Thread类。若想了解更多能够阅读这篇关于如何在Java中建立线程的文章。
当咱们在Java程序中新建一个线程时,它的状态是New。当咱们调用线程的start()方法时,状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间而且讲它们的状态改变为Running。其余的线程状态还有Waiting,Blocked 和Dead。读这篇文章能够了解更多关于线程生命周期的知识。
固然能够,可是若是咱们调用了Thread的run()方法,它的行为就会和普通的方法同样,为了在新的线程中执行咱们的代码,必须使用Thread.start()方法。
咱们可使用Thread类的Sleep()方法让线程暂停一段时间。须要注意的是,这并不会让线程终止,一旦从休眠中唤醒线程,线程的状态将会被改变为Runnable,而且根据线程调度,它将获得执行。
每个线程都是有优先级的,通常来讲,高优先级的线程在运行时会具备优先权,但这依赖于线程调度的实现,这个实现是和操做系统相关的(OS dependent)。咱们能够定义线程的优先级,可是这并不能保证高优先级的线程会在低优先级的线程前执行。线程优先级是一个int变量(从1-10),1表明最低优先级,10表明最高优先级。
线程调度器是一个操做系统服务,它负责为Runnable状态的线程分配CPU时间。一旦咱们建立一个线程并启动它,它的执行便依赖于线程调度器的实现。时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。分配CPU时间能够基于线程优先级或者线程等待的时间。线程调度并不受到Java虚拟机控制,因此由应用程序来控制它是更好的选择(也就是说不要让你的程序依赖于线程的优先级)。
上下文切换是存储和恢复CPU状态的过程,它使得线程执行可以从中断点恢复执行。上下文切换是多任务操做系统和多线程环境的基本特征。
咱们可使用Thread类的joint()方法来确保全部程序建立的线程在main()方法退出前结束。这里有一篇文章关于Thread类的joint()方法。
当线程间是能够共享资源时,线程间通讯是协调它们的重要的手段。Object类中wait()\notify()\notifyAll()方法能够用于线程间通讯关于资源的锁的状态。点击这里有更多关于线程wait, notify和notifyAll.
Java的每一个对象中都有一个锁(monitor,也能够成为监视器) 而且wait(),notify()等方法用于等待对象的锁或者通知其余线程对象的监视器可用。在Java的线程中并无可供任何对象使用的锁和同步器。这就是为何这些方法是Object类的一部分,这样Java的每个类都有用于线程间通讯的基本方法
当一个线程须要调用对象的wait()方法的时候,这个线程必须拥有该对象的锁,接着它就会释放这个对象锁并进入等待状态直到其余线程调用这个对象上的notify()方法。一样的,当一个线程须要调用对象的notify()方法时,它会释放这个对象的锁,以便其余在等待的线程就能够获得这个对象锁。因为全部的这些方法都须要线程持有对象的锁,这样就只能经过同步来实现,因此他们只能在同步方法或者同步块中被调用。
Thread类的sleep()和yield()方法将在当前正在执行的线程上运行。因此在其余处于等待状态的线程上调用这些方法是没有意义的。这就是为何这些方法是静态的。它们能够在当前正在执行的线程中工做,并避免程序员错误的认为能够在其余非运行线程调用这些方法。
在Java中能够有不少方法来保证线程安全——同步,使用原子类(atomic concurrent classes),实现并发锁,使用volatile关键字,使用不变类和线程安全类。在线程安全教程中,你能够学到更多。
当咱们使用volatile关键字去修饰变量的时候,因此线程都会直接读取该变量而且不缓存它。这就确保了线程读取到的变量是同内存中是一致的。
同步块是更好的选择,由于它不会锁住整个对象(固然你也可让它锁住整个对象)。同步方法会锁住整个对象,哪怕这个类中有多个不相关联的同步块,这一般会致使他们中止执行并须要等待得到这个对象上的锁。
使用Thread类的setDaemon(true)方法能够将线程设置为守护线程,须要注意的是,须要在调用start()方法前调用这个方法,不然会抛出IllegalThreadStateException异常。
ThreadLocal用于建立线程的本地变量,咱们知道一个对象的全部线程会共享它的全局变量,因此这些变量不是线程安全的,咱们可使用同步技术。可是当咱们不想使用同步的时候,咱们能够选择ThreadLocal变量。
每一个线程都会拥有他们本身的Thread变量,它们可使用get()\set()方法去获取他们的默认值或者在线程内部改变他们的值。ThreadLocal实例一般是但愿它们同线程状态关联起来是private static属性。在ThreadLocal例子这篇文章中你能够看到一个关于ThreadLocal的小程序。
ThreadGroup是一个类,它的目的是提供关于线程组的信息。
ThreadGroup API比较薄弱,它并无比Thread提供了更多的功能。它有两个主要的功能:一是获取线程组中处于活跃状态线程的列表;二是设置为线程设置未捕获异常处理器(ncaught exception handler)。但在Java 1.5中Thread类也添加了setUncaughtExceptionHandler(UncaughtExceptionHandler eh) 方法,因此ThreadGroup是已通过时的,不建议继续使用。
1 2 3 4 5 6 7 8 |
t1.setUncaughtExceptionHandler(new UncaughtExceptionHandler(){
@Override public void uncaughtException(Thread t, Throwable e) { System.out.println("exception occured:"+e.getMessage()); }
}); |
线程转储是一个JVM活动线程的列表,它对于分析系统瓶颈和死锁很是有用。有不少方法能够获取线程转储——使用Profiler,Kill -3命令,jstack工具等等。我更喜欢jstack工具,由于它容易使用而且是JDK自带的。因为它是一个基于终端的工具,因此咱们能够编写一些脚本去定时的产生线程转储以待分析。读这篇文档能够了解更多关于产生线程转储的知识。
死锁是指两个以上的线程永远阻塞的状况,这种状况产生至少须要两个以上的线程和两个以上的资源。
分析死锁,咱们须要查看Java应用程序的线程转储。咱们须要找出那些状态为BLOCKED的线程和他们等待的资源。每一个资源都有一个惟一的id,用这个id咱们能够找出哪些线程已经拥有了它的对象锁。
避免嵌套锁,只在须要的地方使用锁和避免无限期等待是避免死锁的一般办法,阅读这篇文章去学习如何分析死锁。
java.util.Timer是一个工具类,能够用于安排一个线程在将来的某个特定时间执行。Timer类能够用安排一次性任务或者周期任务。
java.util.TimerTask是一个实现了Runnable接口的抽象类,咱们须要去继承这个类来建立咱们本身的定时任务并使用Timer去安排它的执行。
这里有关于java Timer的例子。
一个线程池管理了一组工做线程,同时它还包括了一个用于放置等待执行的任务的队列。
java.util.concurrent.Executors提供了一个 java.util.concurrent.Executor接口的实现用于建立线程池。线程池例子展示了如何建立和使用线程池,或者阅读ScheduledThreadPoolExecutor例子,了解如何建立一个周期任务。
原子操做是指一个不受其余操做影响的操做任务单元。原子操做是在多线程环境下避免数据不一致必须的手段。
int++并非一个原子操做,因此当一个线程读取它的值并加1时,另一个线程有可能会读到以前的值,这就会引起错误。
为了解决这个问题,必须保证增长操做是原子的,在JDK1.5以前咱们可使用同步技术来作到这一点。到JDK1.5,java.util.concurrent.atomic包提供了int和long类型的装类,它们能够自动的保证对于他们的操做是原子的而且不须要使用同步。能够阅读这篇文章来了解Java的atomic类。
Lock接口比同步方法和同步块提供了更具扩展性的锁操做。他们容许更灵活的结构,能够具备彻底不一样的性质,而且能够支持多个相关类的条件对象。
它的优点有:
可使锁更公平
可使线程在等待锁的时候响应中断
可让线程尝试获取锁,并在没法获取锁的时候当即返回或者等待一段时间
能够在不一样的范围,以不一样的顺序获取和释放锁
阅读更多关于锁的例子
Executor框架同java.util.concurrent.Executor 接口在Java 5中被引入。Executor框架是一个根据一组执行策略调用,调度,执行和控制的异步任务的框架。
无限制的建立线程会引发应用程序内存溢出。因此建立一个线程池是个更好的的解决方案,由于能够限制线程的数量而且能够回收再利用这些线程。利用Executors框架能够很是方便的建立一个线程池,阅读这篇文章能够了解如何使用Executor框架建立一个线程池。
java.util.concurrent.BlockingQueue的特性是:当队列是空的时,从队列中获取或删除元素的操做将会被阻塞,或者当队列是满时,往队列里添加元素的操做会被阻塞。
阻塞队列不接受空值,当你尝试向队列中添加空值的时候,它会抛出NullPointerException。
阻塞队列的实现都是线程安全的,全部的查询方法都是原子的而且使用了内部锁或者其余形式的并发控制。
BlockingQueue 接口是java collections框架的一部分,它主要用于实现生产者-消费者问题。
阅读这篇文章了解如何使用阻塞队列实现生产者-消费者问题。
Java 5在concurrency包中引入了java.util.concurrent.Callable 接口,它和Runnable接口很类似,但它能够返回一个对象或者抛出一个异常。
Callable接口使用泛型去定义它的返回类型。Executors类提供了一些有用的方法去在线程池中执行Callable内的任务。因为Callable任务是并行的,咱们必须等待它返回的结果。java.util.concurrent.Future对象为咱们解决了这个问题。在线程池提交Callable任务后返回了一个Future对象,使用它咱们能够知道Callable任务的状态和获得Callable返回的执行结果。Future提供了get()方法让咱们能够等待Callable结束并获取它的执行结果。
阅读这篇文章了解更多关于Callable,Future的例子。
FutureTask是Future的一个基础实现,咱们能够将它同Executors使用处理异步任务。一般咱们不须要使用FutureTask类,单当咱们打算重写Future接口的一些方法并保持原来基础的实现是,它就变得很是有用。咱们能够仅仅继承于它并重写咱们须要的方法。阅读Java FutureTask例子,学习如何使用它。
Java集合类都是快速失败的,这就意味着当集合被改变且一个线程在使用迭代器遍历集合的时候,迭代器的next()方法将抛出ConcurrentModificationException异常。
并发容器支持并发的遍历和并发的更新。
主要的类有ConcurrentHashMap, CopyOnWriteArrayList 和CopyOnWriteArraySet,阅读这篇文章了解如何避免ConcurrentModificat
ionException。
Executors为Executor,ExecutorService,ScheduledExecutorService,ThreadFactory和Callable类提供了一些工具方法。
Executors能够用于方便的建立线程池。
TCP:面向链接,流的形式进行数据传递,更可靠;Socket,ServerSocket
UDP:使用报文数据包,不面向链接;DatagramSocket、DatagramPacket