JavaSE知识点归纳总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

JavaSE知识点
一、继承,封装,多态
1、分类
我们可以把JAVA中的类分为以下三种:
类:使用class定义且不含有抽象方法的类。

抽象类:使用abstract class定义的类,它可以含有,也可以不含有抽象方法。

接口:使用interface定义的类。

在这三种类型之间存在下面的继承规律:
1.类可以继承(extends)类,可以继承(extends)抽象类,可以继承(implements)接口。

2.抽象类可以继承(extends)类,可以继承(extends)抽象类,可以继承(implements)接口。

3.接口只能继承(extends)接口。

2、继承(inheritance)
继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用父类的功能,但不能选择性地继承父类。

这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。

继承是为了重用父类代码,同时为实现多态性作准备。

构造方法在实例化的时候调用的,而子类既然继承了父类,那就具备了父类所有的属性以及方法,当子类实例化的时候就先调用父类的构造了,如果子类的构造方法中没有通过super显式调用父类的有参构造方法,也没有通过this显式调用自身的其它构造方法,则会默认先调用父类的无参构造方法。

你想那么子类中从父类继承的字段,要谁来初始化呢?
父类中有这些字段的初始化方式,所以最好的选择就是用父类的构造方法。

java创建对象的三个步骤就是,申请内存,调用构造方法,返回对象引用。

3、封装(encapsulation)
类使得数据和对数据的操作集成在一起,从而对使用该类的其他人来说,可以不管它的实现方法,而只管用它的功能,从而实现所谓的信息隐藏。

封装隐藏了类的内部实现机制,从而可以在不影响使用者的前提下改变类的内部结构,同时保护了数据。

4、多态(polymorphism)
方法的重写、重载与动态连接构成多态性。

Java之所以引入多态的概念
对于多态,可以总结它为:
一、使用父类类型的引用指向子类的对象;该引用只能调用父类中定义的方法和变量;
二、如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将
会调用子类中的这个方法;(动态连接、动态调用)
三、变量不能被重写(覆盖),”重写“的概念只针对方法。

5、重写
英文名是overriding,是指在继承情况下,子类中定义了与其基类中方法具有相同型构的新方法,就叫做子类把基类的方法重写了。

这是实现多态必须的步骤。

6、重载
英文名是overloading,是指在同一个类中定义了一个以上具有相同名称,但是型构不同的方法。

在同一个类中,是不允许定义多于一个的具有相同型构的方法的。

7、接口与抽象类
abstract class和interface是Java语言中对于抽象类定义进行支持的两种机制。

在abstract class方式中,可以有自己的数据成员,也可以有非abstarct的成员方法,而在interface方式的实现中,只能够有静态的不能被修改的数据成员(也就是必须是static final的,不过在interface中一般不定义数据成员),所有的成员方法都是abstract的。

从某种意义上说,interface是一种特殊形式的abstract class。

抽象类里面可以有非抽象方法但接口里只能有抽象方法声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。

不能创建abstract 类的实例。

接口(interface)是抽象类的变体。

在接口中,所有方法都是抽象的。

多继承性可通过实现这样的接口而获得。

接口中的所有方法都是抽象的,没有一个有程序体。

接口只可以定义static final 成员变量,instanceof 运算符可以用来决定某对象的类是否实现了接口。

java抽象类的构造方法和普通类的构造方法一样,都是用来初始化类,只是不能直接创建抽象类的实例对象而已。

在继承了抽象类的子类中通过super(参数列表)调用抽象类中的构造方法,可以这么理解吧抽象类就是一个不能实例化的类
不过如果方法加了abstract那么就必须在子类里面重写了
二、Java存储
JAVA的容器---List,Map,Set
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│└Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection 的元素(Elements)。

一些Collection允许相同的元素而另一些不行。

一些能排序而另一些不行。

Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。

所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。

后一个构造函数允许用户复制一个Collection。

如何遍历Collection中的每一个元素?不论Collection 的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。

典型的用法如下:Iterator it = collection.iterator(); // 获得一个迭代子while(it.hasNext()) { Object obj = it.next(); // 得到下一个元素} 由Collection接口派生的两个接口是List和Set。

List接口
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。

用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。

和下面要提到的Set不同,List允许有相同的元素。

除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。

实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。

Sort()对list接口进行排序
LinkedList类
LinkedList实现了List接口,允许null元素。

此外LinkedList提供额外的get,remove,insert方法在LinkedList的首部或尾部。

这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。

注意LinkedList没有同步方法。

如果多个线程同时访问一个List,则必须自己实现访问同步。

一种解决方法是在创建List时构造一个同步的List:List list = Collections.synchronizedList(new LinkedList(...));
ArrayList类
ArrayList实现了可变大小的数组。

它允许所有元素,包括null。

ArrayList没有同步。

size,isEmpty,get,set方法运行时间为常数。

但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。

其他的方法运行时间为线性。

每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。

这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。

当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。

和LinkedList一样,ArrayList也是非同步的(unsynchronized)。

实现长度可变的数组,采用和数组相同的存储方式,被称为动态数组,可以添加任何类型的数据,可以存储不唯一有序的对象
Vector类
Vector非常类似ArrayList,但是Vector是同步的。

由Vector创建的Iterator,虽然和ArrayList创建的Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。

Stack 类
Stack继承自Vector,实现一个后进先出的堆栈。

Stack提供5个额外的方法使得Vector得以被当作堆栈使用。

基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。

Stack刚创建后是空栈。

Set接口
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。

很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。

请注意:必须小心操作可变对象(Mutable Object)。

如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

Hashset 不能保存重复的对象,特点是存储的元素可以是无序排列,集合元素可以是空
Map接口
请注意,Map没有继承Collection接口,Map提供key到value的映射。

一个Map
中不能包含相同的key,每个key只能映射一个value。

Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value 映射。

Hashtable类
Hashtable继承Map接口,实现一个key-value映射的哈希表。

任何非空(non-null)的对象都可作为key或者value。

添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。

Hashtable通过initial capacity和load factor两个参数调整性能。

通常缺省的load factor 0.75较好地实现了时间和空间的均衡。

增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。

使用Hashtable的简单示例如下,将1,2,3放到Hashtable中,他们的key分别是”one”,”two”,”three”:Hashtable numbers = new Hashtable(); numbers.put(“one”, new Integer(1)); numbers.put(“two”, new Integer(2)); numbers.put(“three”, new Integer(3)); 要取出一个数,比如2,用相应的key:
map的public Set keySet()返回所包含键的set集合,因为map中键是不能重复的,所以使用了set集合的不可重复的特性来做返回值类型.循环key
for (String key : map.keySet()) { }
collections 与collection区别
Collection是集合类的上级接口,继承与他的接口主要有Set 和List. Collections 是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作。

CompareTo()比较同类的两对象顺序大小
Sort()对list接口进行排序
Fill()对集合元素进行替换
三、遍历
①Iterator接口
hasnext()是否存在课访问元素
next()返回要访问的下一个元素
②For(元素类型元素名:遍历的对象或者方法){
引用了变量名的java语句
}
四、常用类的用法
1.StringBuffer类和StringBuilder类的区别
所谓的线程安全问题就是同时有多个线程访问同一个资源时引起的数据混乱问题。

StringBuffer是线程安全的,所以当它作为成员变量时不存在线程安全问题。

StringBuilder是线程不安全的,在作为成员变量时有可能出现线程不安全问题。

如果在方法内部使用一个这样的变量,用StringBuilder效率会更高,因为首先StringBuilder没有加锁,其次方法内部不存在线程安全问题。

2.Math.random()与java.util.random()的区别
直接调用Math.random()是产生一个[0,1)之间的随机数,
如果用
java.util.Random random=new Random();random.nextInt()这样产生一个长整型的随机数并且与上一次是一样的,如果过一会再产生就不会一样了,例如:for (int i = 0; i < 10; i++) {
Random random=new Random();
Thread.sleep(100);
System.out.print((int)random.nextInt(100)+"");
}
就是产生不同的随机Long数了
如果想用java.util.Random()产生指定范围的随机数就需要进行求模运算,进行一些处理。

同样可以random.nextInt(100)产生100以内的随机数。

一般最好用nextInt(范围)的,如果不是大量的运算的话,就可以用Math.random了,(因为他可以运算起来慢一些,浮点之后再取整)
(int)(Math.random()*100)
3.数据类型的包装类
Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八个和基本数据类型对应的类统称为包装类,有些地方也翻译为外覆类或数据类型类。

int 是基本类型,直接存数值
Integer是类,产生对象时用一个引用指向这个对象
Java把内存划分成两种:一种是栈内存,另一种是堆内存
在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配
而实际的对象是在存储堆内存中即
int i = 5;//直接在栈中分配空间
Integer i = new Integr(5);//对象是在堆内存中,而i(引用变量)是在栈内存中
在堆中分配的内存,由java虚拟机的自动垃圾回收器来管理.
在这八个类名中,除了Integer和Character类以后,其它六个类的类名和基本数据类型一直,只是类名的第一个字母大写即可。

对于包装类说,这些类的用途主要包含两种:
a、作为和基本数据类型对应的类类型存在,方便涉及到对象的操作。

b、包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。

4.int 和Integer 的区别
java 提供两种不同的类型:引用类型(或者封装类型,Warpper)和原始类型(或内置类型,Primitive)。

Int是java的原始数据类型,Integer是java为int 提供的封装类。

Java为每个原始类型提供了封装类。

引用类型和原始类型的行为完全不同,并且它们具有不同的语义。

引用类型和原始类型具有不同的特征和用法,它们包括:大小和速度问题,这种类型以哪种类型的数据结构存储,当引用类型和原始类型用作某个类的实例数据时所指定的缺省值。

对象引用实例变量的缺省值为null,而原始类型实例变量的缺省值与它们的类型有关。

5.Enum枚举
在JDK1.5 之前,我们定义常量都是:public static fianl.... 。

,有了枚举,可以把相关的常量分组到一个枚举类型里
6.日期时间类
Date:用来表示日期和时间
SimpleData类格式化时间的类
Calendar类用来操作时间的类,是抽象类用getInstance获取其对象
7.String
1.字符串转换成字节数组String s .getBytes()
2.int three = Integer.parseInt(String.valueOf(zuo.charAt(2)));// 取数字字符串的第三个数
3.contains(tuipiao)是否包含
//String类的构造方法
//方法一:String();
//方法二:String(byte[] bytes)
//方法三:String (byte[] bytes,int index,int length)
//方法四:String(char[] value)
//方法五:String(char[] value,int index,int length)
//方法六:String(String str)
......
1、byte[] 转 string
byte[] srtbyte;//声明一个byte字节数组
String res = new String(srtbyte);//使用构造函数转换成字符串
System.out.println(res);
2、string 转 byte[]
String str = "Hello";//声明一个字符串
byte[] srtbyte = str.getBytes();//使用string类的getBytes方法进行转换
也可以将byte转换的时候,设定编码方式相互转换,如下代码:
java中substring的用法
str=str.substring(int beginIndex);
截取掉str从首字母起长度为beginIndex的字符串,将剩余字符串赋值给str;str=str.substring(int beginIndex,int endIndex);截取str中从beginIndex开始至endIndex结束时的字符串,并将其赋值给str;
五、Java输入输出(IO流)
结构图
常用的
1.文件 File
2.字节流
构造方法:
public FileOutputStream(String name):创建一个具有指定名称的文件中写入数据的输出文件流
public FileOutputStream(String name,boolean append):创建一个向具有指定name的文件中写入数据的输出文件流。

如果第二个参数为true,则将字节写入文件末尾处,而不是写入文件开始处
public FileOutputStream(File file):创建一个向指定File对象表示的文件中写入数据的文件输出流
public FileOutputStream(File file,boolean appended):创建一个向指定File对象表示的文件中写入数据的文件文件输出流。

如果第二个参数为true,则将字节写入文件末尾处,而不是写入文件开始处。

总结:
1、FileInputStream是InputStream类(字节流输入)的子类,以字节流方式读取文件;FileInputStream的构造函数参数可以是File文件,也可以是字符串,但实际上使用File文件会更加规范。

2、类似的,FileOutputStream是OutputStream类的子类,以字节流方式写入文件。

如果进行写操作的文件不存在,责自动创建该文件。

如果文件所在的路径也不存在则报错。

3、与File类不同(File类关注的是文件在磁盘上的存储),FileInputStream,FileOutputStream关注是的文件的内容
4.采用BufferOutputStream 类将FileOutputStream作为参数新建一个对象便可以提高文件的读写效率
输入流FileInputStream
上面的程序存在问题是,每读取一个自己我都要去用到FileInputStream,我输出的结果是“---长度是:64982 字节”,那么进行了64982次操作!可能想象如
果文件十分庞大,这样的操作肯定会出大问题,所以引出了缓冲区的概念。

(详解BufferedInputStream 和BufferedOutputStream)
通常InputStream的read()返回-1后,说明到达文件尾,不能再读取。

输出流FileOutputStream
InputStream是所有字节输出流的父类,子类有ByteArrayOutputStream,FileOutputStream,ObjectOutputStreanm,这里说下FileOutputStream
我以一个文件复制程序来说,顺便演示一下缓存区的使用。

(Java I/O默认是不缓冲流的,所谓“缓冲”就是先把从流中得到的一块字节序列暂存在一个被称为buffer的内部字节数组里,然后你可以一下子取到这一整块的字节数据,没有缓冲的流只能一个字节一个字节读,效率孰高孰低一目了然。

有两个特殊的输入流实现了缓冲功能,一个是我们常用的BufferedInputStream.)
扩展:bit和byte同译为"比特",都是数据量度单位,bit=“比特”或“位,byte=字节即1byte=8bits,两者换算是1:8的关系。

bit 电脑记忆体中最小的单位,在二进位电脑系统中,每一bit 可以代表0 或 1 的数位讯号。

一个Byte由8 bits 所
}
}
}
/**************************************************************************************************/ 1.numberRead的目的在于防止最后一次读取的字节小于b的长度(使用缓冲流则省略这一步)
read(byte[] b)从此输入流中将最多b.length 个字节的数据读入一个byte
数组中,返回读入缓冲区的字节总数,如果因为已经到达文件末尾而没有更多的数据,则返回-1。

write(byte[] b, int off, int len) 将指定byte 数组中从偏移量off 开始的
len 个字节写入此文件输出流。

2.构造FileOutPutStream的实例对象,先定义一个File类文件的做法比较规范,通用
3.此类写法定义直接数组的弊端
byte[] b = new byte[in.available()];
in.read(b);
out.write(b);
在进行网络操作时往往出错,因为你调用available()方法时,对发发送的数据可能还没有到达,你得到的in.available()是0。

available()返回下一次对此输入流调用的方法可以不受阻塞地从此输入流读取(或跳过)的估计剩余字节数,使用available()方法可以获得还有多少字节可以读取.
字节流与缓冲区
BufferedInputStream 和BufferedOutputStream
java.io.BufferedInputStream与java.io.BufferedOutputStream可以为InputStream、OutputStream类的对象增加缓冲区功能,构建BufferedInputStream实例时,需要给定一个InputStream类型的实例,实现BufferedInputStream时,实际上最后是实现InputStream实例.同样地,在构建BufferedOutputStream时,也需要给定一个OutputStream实例,实现BufferedOutputStream时,实际上最后是实现OutputStream实例. BufferedInputStream的数据成员buf是一个位数组,默认为2048字节,BufferedOutputStream的数据成员buf 也是一个位数组,默认为512字节.
例2是对例1的改写,不用自行设定缓冲区,比较简单且有效率.
/content-10619495.html 3.字符流
顾名思义,就是操作字符文件的流
字符流与PrintWriter
字符流与缓冲区
文章来源:/u011627980/article/details/51970432
4.字节流拓展
序列化与反序列化
序列化就是将对象存储到特定的存储介质的过程在序列化的过程,会将对象的共有属性和私有属性包括类名转换成字节流,然后把字节流写入到数据流,存储到存储介质中,这里说的存储介质通常指文件,
3.读写对象:ObjectInputStream 和ObjectOutputStream ,该流允许读取或写入用户自定义的类,但是要实现这种功能,被读取和写入的类必须实现Serializable接口,其实该接口并没有什么方法,可能相当于一个标记而已,但是确实不合缺少的。

关键类和方法,序列化objiectoutputstream的writerobject()方法和反序列化objiectInputstream的Readerobject()方法,被序列化的对象必须实现Serializable接口
扩展:有时没有必要存储整个对象的信息,而只是要存储一个对象的成员数据,
成员数据的类型假设都是Java的基本数据类型,这样的需求不必使用到与Object输入、输出相关的流对象,可以使用DataInputStream、DataOutputStream 来写入或读出数据。

重定向
字节打印流PrintStream
PrintStream 说这个名字可能初学者不熟悉,如果说System.out.print()你肯定熟悉,System.out这个对象就是PrintStream,这个我们不做过多示例
System.in流与System.out流决定了输入或输出的地方将不是控制套而是指定的
文件里(重定向)
PrintStream ps=new PrintStream(new FileOutputStream("E:\\Workspaces\\小说阅读器\\download\\古侠今遇.txt"));//不再输出到屏幕上,而是输入到指定文件夹! System.setOut(ps);//重定向
System.out.println("默认输出到控制台的这一句,输出到了文件古侠今遇.txt");
扩展
PrintStream
PrintStream在OutputStream基础之上提供了增强的功能,即可以方便地输出各种类型的数据(而不仅限于byte型)的格式化表示形式。

PrintStream的方法从不抛出IOEceptin
PrintWriter
PrintWriter提供了PrintStream的所有打印方法,其方法也从不抛出IOException。

与PrintStream的区别:
作为处理流使用时,PrintStream只能封装OutputStream类型的字节流,而PrintWriter既可以封装OutputStream类型的字节流,还能够封装Writer类型的字符输出流并增强其功能。

六、反射
一,反射常用API
Class类:进行对对象的获取及创建,利用自己的方法获取另一个对象的类赋给filed 与method对象
1.Field类特有方法get()与set (), setaccessible()
2.Method类特有方法invoke(对象,对象参数)返回值为对象类型
3.Constructor类
二获取对象的三种方法
Getclass方法.class属性调用class类的forname方法
Class的很多方法可以获得对象的方法和属性
三利用反射创建类的对象
Class对象的newinstance()方法(只限于无参构)或者用户constructor对象创建
四访问类的属性
Field对象的get与set方法
SetAccessible进行取消私有限制
五访问类的方法
调用类的method对象的invoke方法反调(方法调对象)
六用array类动态创建数组
Newinstance方法进行创建
Get与set方法进行赋值与获取!
七、多线程
最近手上拿到一个程序,其中是一个视频监控的小程序,其中调用了线程,但是调试的时候出现的BUG,调试了N久,无果。

最后,我把线程函数用一个普通的函数替代了,就没有错误了,后来,变思索,此处为何要用线程,不用不行吗?调用线程的有何优点?何时适用?
CPU是以时间片的方式为进程分配CUP处理时间的,当一个进程以同步的方式去完成几件事情时,此进程必须完成了第一件事情以后再做第二件事,如此按顺序地向CPU请求完成要做的事情。

在此单线程的工作模式下,如果把CUP看作是一共有100个时间片的话,CPU可能一直都只是花了其中的10个时间片来处理当前进程所要做的事情,只是用到了CPU的10%的时间片,而其他时间都白白浪费了,当然,实际上CPU的工作模式还是做完一件事以后再去做另一件事,只是CUP的处理速度非常快,很快就处理完成所请求的情事。

为了提高CPU的使用率,采用多线程的方式去同时完成几件事情而互不干扰,如当前进程要完成三件事情1、2、3,那么CPU会分别用10%的时间来同时处理这3件事情,从而让CPU的使用率达到了30%,大大地提高了CPU的利用率。

多线程的好处在处理一些特殊的场合其优势尤其明显。

比如下载文件,你要一边下载一边显示进度一边保存,在这种情况下,如果没有用多线程的话,没有意外的话一般都会把主线程阻塞,比如进度条的进度根本没有随着已下载的量而变化,堪至是整个窗体都动不了,用多线程就可以很好地解决这个问题。

这里有一个生活实例可能更好地去理解多线程:回去看你女朋友做饭,正常的话她都会把洗好的菜(肉)先放到锅里煮,然后一边洗别的菜或处理别的事情,如:洗碗、收拾桌台准备开饭,人还是一个人,但她同时做几件事情,这样就可
以大大地提高效率。

总的一句话就是:CPU还是要花同样多的时间去完成所有的事情,但多线程可以让CPU掺插地同时做多件事情,在视觉上让用户觉得计算机在同时帮他处理多件事情,更好地改善用户体验。

了解了多线程的好处以后,就要了解应该在什么样的情况下使用多线程技术。

因为并不是说所有情况下用多线程都是好事,因为多线程的情况下,CPU还要花时间去维护,CPU处理各线程的请求时在线程间的切换也要花时间,所以一般情况下是可以不用多线程的,用了有时反而会得不偿失。

大多情况下,要用到多线程的主要是需要处理大量的IO操作时或处理的情况需要花大量的时间等等,比如:读写文件、视频图像的采集、处理、显示、保存等。

何时使用多线程技术,何时避免用它,是我们需要掌握的重要课题。

多线程技术是一把双刃剑,在使用时需要充分考虑它的优缺点。

多线程处理可以同时运行多个线程。

由于多线程应用程序将程序划分成多个独立的任务,因此可以在以下方面显著提高性能:
优点:
(1)多线程技术使程序的响应速度更快,因为用户界面可以在进行其它工作的同时一直处于活动状态;
(2)当前没有进行处理的任务时可以将处理器时间让给其它任务;
(3)占用大量处理时间的任务可以定期将处理器时间让给其它任务;
(4)可以随时停止任务;
(5)可以分别设置各个任务的优先级以优化性能。

是否需要创建多个线程取决于各种因素。

在以下情况下,最适合采用多线程处理:
(1)耗时或大量占用处理器的任务阻塞用户界面操作;
(2)各个任务必须等待外部资源(如远程文件或Internet连接)。

同样的,多线程也存在许多缺点,在考虑多线程时需要进行充分的考虑。

多线程的主要缺点包括:
(1)等候使用共享资源时造成程序的运行速度变慢。

这些共享资源主要是独占性的资源,如打印机等。

(2)对线程进行管理要求额外的CPU开销。

线程的使用会给系统带来上下文切换的额外负担。

当这种负担超过一定程度时,多线程的特点主要表现在其缺点上,比如用独立的线程来更新数组内每个元素。

(3)线程的死锁。

即较长时间的等待或资源竞争以及死锁等多线程症状。

(4)对公有变量的同时读或写。

当多个线程需要对公有变量进行写操作时,后一个线程往往会修改掉前一个线程存放的数据,从而使前一个线程的参数被修改;另。

相关文档
最新文档