近期学习总结

来源:互联网 发布:布兰迪斯大学 知乎 编辑:程序博客网 时间:2024/05/29 11:44

学习总结

多线程

多线程的优势:

1.提高界面程序的响应速度.

2.充分利用系统资源.

在线程编程中,继承Thread类或实现Runnable接口的类才具备多线程的能力。

线程的生命周期与主要的线程状态:

1.新建状态(New).

2.就绪状态(Runnable).

3.运行状态(Run).

4.阻塞状态(Block).

5.终止状态(Dead).

线程调度

1.线程睡眠sleep()

2.暂停线程yield()

3.连接线程join()

4.中断线程interrupt()

线程的通信

为避免死锁,就应该让线程在进入阻塞状态时尽量释放其锁定的资源,以为其他的线程提供运行的机会,Object类中定义了几个有用的方法:wait()、notify()、notifyAll()。

1.wait():被锁定的对象可以调用wait()方法,这将导致当前线程被阻塞并释放该对象的互斥锁,即解除了wait()方法当前对象的锁定状态,其他的线程就有 机会访问该 对象。

2.notify():唤醒调用wait()方法后被阻塞的线程。每次运行该方法只能唤醒一个线程。

3.notifyAll():唤醒所有调用wait()方法被阻塞的线程。

定时器:Timer和TimerTask

¯ java.util包中的Timer和TimerTask类也可实现多线程

¯ Timer类实现的是类似闹钟的功能,也就是定时或者每隔一定时间间隔触发一次线程。

¯ TimerTask类是一个抽象类,该类实现了Runnable接口,具备多线程的能力。

¯ 通过继承TimerTask类创建子类,使该子类获得多线程的能力,将需要多线程执行的代码书写在run方法内部,然后通过Timer类启动线程的执行。

JDBC

l 数据库驱动

l SUN公司为统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。

l JDBC全称为:Java Data Base Connectivity(java数据库连接),它主要由接口组成。

l 组成JDBC的2个包:

l  java.sql

l  javax.sql

l 开发JDBC应用需要以上2个包的支持外,还需要导入相应JDBC的数据库实现(即数据库驱动)。

运用

1.加载驱动

Class.forName("com.mysql.jdbc.Driver"【驱动名称】);

2.创建连接

Connectioncon=DriverManager.getConnection(url【标识数据库的位置】,user,password);

url的写法:jdbc【协议】:mysql【子协议】:[]//localhost:3306【主机,端口】/test【数据库名称】

3.创建语句对象

Statement st=con.createStatement();

4.执行sql语句

ResultSet rs=st.executeQuery(sql【sql查询语句】);

5.遍历

while (rs.next()){

System.out.print(rs.getObject("id"));

......

}

6.释放资源

rs.close();

st.close();

con.close();

JDBC调用存储过程

l 编写存储过程

l 得到CallableStatement,并调用存储过程:

l 设置参数,注册返回值,输出:

事务处理

l 事务的概念

• 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。

l 数据库开启事务命令

• start transaction 开启事务

• Rollback 回滚事务

• Commit 提交事务

l 当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。

l JDBC控制事务语句

• Connection.setAutoCommit(false);start transaction 开启事务

• Connection.rollback(); rollback 回滚事务

• Connection.commit(); commit 提交事务

l 设置事务回滚点

• Savepoint sp =conn.setSavepoint();

• Conn.rollback(sp);

• Conn.commit(); //回滚后必须要提交

创建JDBC的事务主要分以下步骤:

1.设置事务的提交方式为非自动提交:

conn.setAutoCommit(false);

2.将需要添加事务的代码放入try,catch块中。

3.在try块内添加事务的提交操作,表示操作无异常,提交事务。

conn.commit();

4.在catch块内添加回滚事务,表示操作出现异常,撤销事务:

conn.rollback();

5.设置事务提交方式为自动提交:

conn.setAutoCommit(true);

事务的特性

l 原子性
原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

l 一致性
事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

l 隔离性
事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离。

l 持久性
持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。

数据库共定义了四种隔离级别:

Serializable:可避免脏读、不可重复读、虚读情况的发生。(串行化)(序列化)

Repeatable read:可避免脏读、不可重复读情况的发生。(可重复读)

Read committed:可避免脏读情况发生(读已提交)。

Read uncommitted:最低级别,以上情况均无法保证。(读未提交)

JDBC处理大数据批处理

实现批处理的第二种方式:

处理大数据就是把大数据或者二进制数据保存到数据库中。

基本概念:大数据也称之为LOB(Large Objects)LOB又分为:clobblob

clob用于存储大文本。Text

blob用于存储二进制数据,例如图像、声音、二进制文等。

Text类型

对于MySQL中的Text类型,可调用如下方法设置:

MySQL中的Text类型,可调用如下方法获取:

BLOB类型

对于MySQL中的BLOB类型,可调用如下方法设置:

MySQL中的BLOB类型,可调用如下方法获取:

Oracle定义了一个BLOB字段用于保存二进制数据,但这个字段并不能存放真正的二进制数据,只能向这个字段存一个指针,然后把数据放到指针所指向的OracleLOB段中, LOB段是在数据库内部表的一部分。因而在操作Oracle的Blob之前,必须获得指针(定位器)才能进行Blob数据的读取和写入。

l 插入空blob
insert into test(id,image) values(?,empty_blob());

l 获得blob的cursor
select image from test where id= ? for update;
Blob b = rs.getBlob(“image”);

• 注意: 须加for update,锁定该行,直至该行被修改完毕,保证不产生并发冲突。

l 利用 io,和获取到的cursor往数据库读写数据

批处理

当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。

l 实现批处理有两种方式,第一种方式:

• Statement.addBatch(sql) list

l 实现批处理的第二种方式:

• PreparedStatement.addBatch()

l 采用Statement.addBatch(sql)方式实现批处理:

• 优点:可以向数据库发送多条不同的SQL语句。

• 缺点:

• SQL语句没有预编译。

• 当向数据库发送多条语句相同,但仅参数不同的SQL语句时,需重复写上很多条SQL语句。

l 采用PreparedStatement.addBatch()实现批处理

• 优点:发送的是预编译后的SQL语句,执行效率高。

• 缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。

网络编程

¯ 网络基本概念

µ 计算机网络,就是把分布在不同地理区域的计算机与专门的外部设备用通信线路互连成一个规模大、功能强的网络系统,从而使众多的计算机可以方便地互相传递信息,共享硬件、软件、数据信息等资源。

µ 网络体系结构:国际标准化组织ISOl978年提出开放系统互连参考模型,即著名的OSIOpen System Interconnection)模型。该模型把计算机网络分成物理层、数据链路层、网络层、传输层、会话层、表示层、应用层等七层。

¯ 通信协议
计算机网络中实现通信必须有一些约定,即通信协议。对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。

µ TCP协议:提供可靠的数据传输服务的规则。

µ IP协议进行IP数据包的分割和组装。

但是通过IP协议并不能清楚地了解到数据包是否顺利地发送给目标计算机。而使用TCP协议,它将数据包成功发送给目标计算机后,会要求发送一个确认,如果在某个时间内没有收到确认,TCP将重新发送数据包。

¯ IP地址和端口号

µ IP地址:为实现网络中不同的计算机之间的通信,在网络中的每台机器都必须有一个与众不同的标识,这就是IP地址(IP Address)。

ü 格式:数字型、32位、由48位的二进制数组成。一般表示为十进制形式(40~255的十进制整数),中间用圆点隔开,如:166.111.78.98

ü 域名地址:也是分段表示的,便于记忆的、字符串形式。

µ 端口:一个16位的整数,用于表示数据交给哪个通信程序处理。因此,端口就是应用程序与外界交流的出入口,它是一种抽象的软件结构,包括一些数据结构和I/O(基本输入/输出)缓冲区。

端口的分类:

1公认端口:从01023,它们紧密绑定(Binding)一些服务。

2注册端口:从102449151。它们松散地绑定一些服务。

3动态和/或私有端口:从4915265535,这些端口是应用程序使用的动态端口,应用程序一般不会主动使用这些端口。

¯ InetAddress:用于描述IP地址的对象

µ InetAddress类没有提供构造方法,而是提供了两个静态方法来获取InetAddress实例
getByName(String host):根据主机获取对应的InetAddress对象。
getByAddress(byte[] addr):根据原始IP地址来获取对应的InetAddress对象。

¯ 什么是UDP协议?

µ UDP( User Datagram Protocol )协议是用户数据报,在网络中它与TCP协议一样用于处理数据包。在OSI模型中,在第四层——传输层,处于IP协议的上一层。

µ UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

¯ Java中操纵UDP
使用位于JDKJava.net包下的DatagramSocketDatagramPacket类,可以非常方便地控制用户数据报文。

µ DatagramSocket类:创建接收和发送UDPSocket实例

¯ DatagramSocket():创建实例。通常用于客户端编程,它并没有特定监听的端口,仅仅使用一个临时的。

¯ DatagramSocket(int port):创建实例,并固定监听Port端口的报文。

¯ DatagramSocket(int port, InetAddress localAddr):这是个非常有用的构建器,当一台机器拥有多于一个IP地址的时候,由它创建的实例仅仅接收来自LocalAddr的报文。

ü receive(DatagramPacket d):接收数据报文到d中。receive方法产生一个阻塞

ü send(DatagramPacket d):发送报文d到目的地。

ü setSoTimeout(int timeout):设置超时时间,单位为毫秒。

ü close():关闭DatagramSocket。在应用程序退出的时候,通常会主动释放资源,关闭Socket,但是由于异常地退出可能造成资源无法回收。所以,应该在程序完成时,主动使用此方法关闭Socket,或在捕获到异常抛出后关闭Socket

ü DatagramPacket:用于处理报文,将byte数组、目标地址、目标端口等数据包装成报文或者将报文拆卸成byte数组。

ü DatagramPacket(byte[] buf, int length, InetAddress addr, int port):从buf数组中,取出length长的数据创建数据包对象,目标是addr地址,port端口。

ü DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):从buf数组中,取出offset开始的、length长的数据创建数据包对象,目标是addr地址,port端口。

ü DatagramPacket(byte[] buf, int offset, int length):将数据包中从offset开始、length长的数据装进buf数组。

ü DatagramPacket(byte[] buf, int length):将数据包中length长的数据装进buf数组。

ü getData():它从实例中取得报文的byte数组编码。

Java中实现TCP协议编程

¯ ServerSocket:编写TCP网络服务程序,首先要用到java.net.ServerSocket类用以创建服务器Socket

µ 构造方法:

ü ServerSocket(int port):创建绑定到特定端口的服务器套接字

ü ServerSocket(int port, int backlog):利用指定的backlog(服务器忙时保持连接请求的等待客户数量),创建服务器套接字并将其绑定到指定的本地端口号。

ü ServerSocket(int port, int backlog, InetAddress bindAddr):使用指定的端口、侦听 backlog和要绑定到的本地 IP地址创建服务器。

¯ Socket:客户端要与服务器建立连接,必须先创建一个Socket对象

µ 常用构造方法

ü Socket(String host, int port):创建一个流套接字并将其连接到指定主机上的指定端口号。

ü Socket(InetAddress address, int port):创建一个流套接字并将其连接到指定 IP地址的指定端口号。

/*客户端通过键盘录入信息,发送到服务器端

服务器端收到信息后,将信息转为大写返回给客户端。*/

Java SE增强

静态导入

l JDK 1.5 增加的静态导入语法用于导入指定类的某个静态属性值(方法)或全部静态属性值(方法)

l 语法:

• Import static 包名.类名.静态属性|静态方法|*

l 静态导入语句使用 import static 语句

• 导入指定类的单个静态属性:

import static java.lang.System.out

• 导入指定类静态方法
import static java.lang.Math.max

• 导入指定类全部静态属性和方法

import static java.lang.Math.*

自动装箱/拆箱

l 自动装箱(autoboxing):把一个基本数据类型直接赋给对应的包装类变量, 或者赋给 Object 变量

l 自动拆箱:把包装类对象直接赋给一个对应的基本类型变量

事例:

Integer i=1; //自动装箱

//相当于Integer i=new Integer(1);

intj=i;//自动拆箱

应用

List list = new ArrayList();

list.add(1);

int j = (Integer)list.get(0);//自动装箱

增强for循环

l 引入增强for循环的原因:在JDK5以前的版本中,遍历数组或集合中的元素,需先获得数组的长度或集合的迭代器,比较麻烦!

l 因此JDK5中定义了一种新的语法——增强for循环,以简化此类操作。增强for循环只能用在数组、或实现Iterator接口的集合类上

l 使用 foreach 循环遍历数组和集合元素时, 无须获得数组和集合长度, 无须根据索引来访问数组元素和集合元素, foreach 循环自动遍历数组和集合的每个元素

l 语法格式:

• for ( type 变量名:集合变量名 ) { … }

for(type varName : array| collection){

//varName 自动迭代访问每一个元素

}

事例:

@Test

public void test1(){

String[] name={"aa","bb","cc"};

for(String str:name){

System.out.println(str);

}

}

@Test

public void test2(){

List list=newArrayList();

list.add("aaa");

list.add("bbb");

list.add("ccc");

for(Object str:list){

System.out.println(str);

}

}

可变参数

l 从 JDK 1.5 开始, Java 允许定义形参长度可变的参数,从而允许为方法指定数量不确定的形参

l 若在定义方法时, 在最后一个形参的类型后增加三点(…, ...位于变量类型和变量名之间,前后有无空格都可以)则表明该形参可以接受多个参数值, 多个参数值被当成数组传入

l 可变形参只能处于形参列表的最后, 所以一个方法最多只能有一个长度可变的形参

l 调用包含一个可变形参的方法时, 可以为该形参传入多个参数或一个数组

l 调用可变参数的方法时, 编译器为该可变参数隐含创建一个数组, 在方法体中以数组的形式访问可变参数

事例:

枚举类

l 为什么需要枚举?

• 一些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的值,此类问题在JDK5以前采用自定义带有枚举功能的类解决,Java5以后可以直接使用枚举予以解决。

l JDK5新增的 enum 关键字用于定义一个枚举类。

l 枚举类对象的属性不应允许被改动, 所以应该使用 privatefinal 修饰

l 枚举类的使用 private final 修饰的属性应该在构造器中为其赋值

l 若枚举类显式的定义了带参数的构造器, 则在列出枚举值时也必须对应的传入参数

l Java中声明的枚举类,均是java.lang.Enum类的孩子,它继承了Enum类的所有方法。常用方法:

• name():返回此枚举常量的名称,在其枚举声明中对其进行声明

• ordinal():返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。

• valueof(ClassenumClass, String name):返回带指定名称的指定枚举类型的枚举常量。 静态方法

• values()此方法虽然在JDK文档中查找不到,但每个枚举类都具有该方法,它遍历枚举类的所有枚举值非常方便。

内省(Introspector)

为什么要学内省?

开发框架时,经常需要使用java对象的属性来封装程序的数据,每次都使用反射技术完成此类操作过于麻烦,所以sun公司开发了一套API,专门用于操作java对象的属性。

什么是Java对象的属性和属性的读写方法?

内省访问JavaBean属性的两种方式:

通过PropertyDescriptor类操作Bean的属性

通过Introspector类获得Bean对象的 BeanInfo,然后通过 BeanInfo 来获取属性的描述器( PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的getter/setter 方法,然后通过反射机制来调用这些方法。

内省是 Java 语言对 Bean 类属性的一种缺省处理方法。例如类 A 中有属性 name, 可以通过 getName,setName 来得到其值或者设置新的值。通过 getName/setName 来访问 name 属性,这是默认的规则。 Java 中提供了一套 API 来访问某个属性的 getter/setter 方法。

一般的做法是通过类Introspector 来获取某个对象的BeanInfo 信息,然后通过BeanInfo 来获取属性的描述器(PropertyDescriptor ),通过这个属性描述器就可以获取某个属性对应的 getter/setter 方法,然后通过反射机制来调用这些方法

内省—beanutils工具包

Sun公司的内省API过于繁琐,所以Apache组织结合很多实际开发中的应用场景开发了一套简单、易用的API操作Bean的属性——BeanUtils

Beanutils工具包的常用类:

BeanUtils

PropertyUtils

ConvertUtils.regsiter(Converter convert,Class clazz)

后记:

开学几经一月有余这个月主要加强了java后半部分,由于上学期没有就其进行深入的讲解,这学期老师对其进行了讲解,综合来说线程部分学习的比较好,jdbc以及网络有些欠缺,正在努力提高SE比较简单所以学习起来比较轻松。

老师评价

我们的主要授课老师李老师非常的认真负责讲课认真,同时也给予我们自己练习思考的时间,课后辅导也十分尽心尽力。

原创粉丝点击