ORITY(最高)和Thread.NORM?PRIORITY(标准)。 (6)start(),启动线程,让线程从新建状态到就绪状态。 (7)run(),实现线程行为(操作)的方法。
(8)sleep(intdt),让线程休眠dt时间,单位是毫秒。由于sleep()方法可能会产生InterruptedException异常,应将sleep()方法写在try块中,并用catch块处理异常。sleep()方法是static方法,不可重载。
(9)currentThread(),获得当前正在占有CPU的那个线程。 2.用Thread子类实现多线程
用Thread子类实现多线程,得先声明一个Thread类的子类,并在子类中重新定义run()方法。当程序需要建立线程时,就可创建Thread子类的实例,并让创建 的线程调用start()方法,这时,run()方法将自动执行。
8.2.2 Runnable接口
Java.lang.Runnable接口,只有run()方法需要实现。一个实现Runnable接口的类实际上定义了一个在主线程之外的新线程的操作。用Runnable接口实现多线程的主要工作是:声明实现Runnable接口的类,在类内实现run()方法;并在类内声明线程对象,在init()方法或start()方法中创建新线程,并在start()方法中启动新线程。 8.3 线程互斥和同步
通常情况下,程序中的多个线程是相互协调和相互联系的,多线程之间有互斥和同步。 8.3.1 线程互斥
先看线程之间需要互斥的情况。设有若干线程共享某个变量,且都对变量有修改。如果它们之间不考虑相互协调工作,就会产生混乱。比如,线程A和B共用变量x,都对x执行增1操作。由于A和B没有协调,两线程对x的读取、修改和写入操作相互交叉,可能两个线程读取同样的x值,一个线程将修改后的x新值写入到x后,另一个线程也把自己对x的修改后的新值写入到x。这样,x只记录后一个线程的修改作用。多线程互斥使用共享资源的程序段,在操作系统中称为临界段。临界段是一种加锁的机制,与多线程共享资源有关。临界段的作用是在任何时刻一个共享资源只能供一个线程使用。当资源未被占用,线程可以进入处理这个资源的临界段,从而得到该资源的使用权;当线程执行完毕,便退出临界段。如果一个线程已进入某个共享资源的临界段,并且还没有使用结束,其他线程必须等待。在Java语言中,使用关键字synchronized定义临界段,能对共享对象的操作上锁。 8.3.2 线程同步
多线程之间除有互斥情况外,还需要同步。当线程A使用到某个对象,而此对象又需要线程B修改后才能符合本线程的需要,这时线程A就要等待线程B完成修改工作。这种线程相互等待称为线程的同步。为实现同步,Java语言提供wait()、notify()和notifyAll
()三个方法供线程在临界段中使用。在临界段中使用wait
()方法,使执行该方法的线程等待,并允许其他线程使用这个临界线。wait()方法常用以下两种格式:
wait(),让线程一直等待,直到被notify()或notifyAll()方法唤醒。
wait(longtimeout),让线程等待到被唤醒,或经过
指定时间后结束等待。当线程使用完临界段后,用notify()方法通知由于 想使用这个临界段而处于等待的线程结束等待。notify
()方法只是通知第一个处于等待的线程。如果某个线程在使用完临界线方法后,其他早先等待的线程都可结束等待,重新竞争CPU,则可以使用notifyAll()方法。
9.1 字节流和字符流
对Java程序而言,输入/输出包括:对外设通道的输入/输出、对文件的读和写、对网络数据的读和写。Java语言采用流(stream)的机制实现输入和输出。实现输入/输出操作的类库在java.io包中。包中有一组支持打开流、向流写数据、从流读取数据和关闭流等操作的类,要使用这些类,程序必须导入java.io包。 9.1.1 File对象
建立输入输出流对象之前可以先建立一个File(文件)对象。File对象是File类的实例。
9.1.2 流对象
根据输入输出数据的类型是字节还是字符,java.io提供两种基本抽象类:一种用于读写字节,另一种用于读写字符。字节流用于读写二进制数据,比如图像和声音文件等。字节流数据是8位的,由InputStrearn类和Output?Stream类为字节流提供API和部分实现。字节流读和写操作由FileInputStream类和FileOutputStream类提供支持。它们分别是InputStream 类和 OutputStream类的子类。
字符流数据是16位的Unicode字符,字符流能处理Unicode字符集中的任何字符,由Reader数和 Writer类为字符流程提供 API和部分实现。读和写操作由FileReader类和 FileWriter类提供支持。它们分别是Reader和 Writer的子类。 1.建立流对象
通过流的构造方法建立流对象,创建输入输出流对象的常用构造方法有2种:
(1)FileInputStream(Stringname),直接用指定的文 件名创建输入流。
(2)FileInputStream(Filefinename),用文件对象创建输入流。
2.输入流的常用方法
FileInputStream类包含下面用于读字节和字节数组的方法: (1)intread()
(2)intread(byteb[])
(3)intread(byteb[],intoff,intlen)
使用以上三个方法时,如果在读数据之前,已到达输入流的末端位置,没有读入一个字节数据,用返回-1表示流在读之前已结束。
FileReader类包含下面用于读字符和字符数组的 方法:
(1)intread()
(2)intread(charb[])
(3)intread(charb[],intoff,intlen) 对于输入流,另外还有一个常用的方法:
longskip(longn),从输入流的当前读位置起向前移动n个字节/字符,并返回实际跳过的字节/字符数。 3.输出流的常用方法
FileOutputStream类包含下面用于输出字节和字节数组的方法: (1)intwrite(intc),输出一个字节。
(2)intwrite(byteb[]),输出存于字节数组b中的字节数据。 (3)intread(byteb[],intoff,intlen),输出字节数 组b中从下标off开始的多至len个字节。
FileWriter类也包含用于输出字符和字符数组的
方法:
(1)intwrite(intc),输出一个字符。
(2)intwrite(charb[]),输出存于字符数组b中的字符数据。
(3)intread(charb[],intoff,intlen),输出字符数组b中从下标off开始的多至len个字符。对于输出流,另外还一个常用方法: voidflush(),刷空输出流,并且输出所有存储在缓冲区的内容。 流使用结束后,关闭流并且释放与该流相关的资源用方法close()。 9.2 缓冲式输入输出
程序要采用缓冲式输入,只要先创建FileReader对象,再利用FileReader对象创建BufferedReader对象,习惯称为将FileReader对象接到BufferedReader对象上。这样,就可以对BufferedReader对象使用readLine
()方法,按行输入文件内容。
BufferedWriter类是提供缓冲式输出的类。程序只要先创建FileWriter对象,再利用FileWriter对象创建BufferedWriter对象,习惯称为将FileWriter对象接到BufferedWriter对象上。对 BufferedWriter对象使用write()方法就能实现缓冲式输出。 9.3 随机访问
文件随机访问可利用 RandomAccessFile类实现,RandomAccessFile类创建的流既可以随机输出,也可以随机输入。 9.4 文件对话框
可以用javax.swing包中的类JFileChooser实现打开和保存文件对话框。
10.1 Java网络编程基础
Java语言的优势之一是Java程序能访问网络资源。 Java提供一系列的类支持Java程序访问网络资源。 10.1.1 IP地址和InetAddress类 1.TCP/IP协议和IP地址
为了进行网络通信,通信双方必须遵守通信协议。目前最广泛使用的是TCP/IP协议,它是Internet中各方所遵循的公共协议。TCP(TransportControlProtocol)是一种传输控制协议,IP(InternetProtocol)是一种网际协议,TCP/IP代表这两个协议的结合。 2.InetAddress类
java.net包中有InetAddress类的定义,InetAddress 类的对象用于存储IP地址和域名。 10.1.2 统一资源泉定位等URL 1.URL类
java.net包有URL类,一个URL对象可以表示一个网络资源。程序利用URL对象能实现Internet寻址、网络资源的定位连接,在客户机与服务器之间直接访问等。 2.URLConnection类
要接收和发送信息还需用URLConnection类,程序获得一个 URLConnection对象,相当于完成对指定URL的一个HTTP连接。创建一个URL对象,然后利用URL对象的openConnection()方法,从系统获得一个URLConnection对象。程序有了 URLConnection对象后,就可使用 URLConnection类提供的以下方法获得流对象和实现网络连接。 10.1.3 客户机/服务器模式
网络应用模式主要有:主机/终端模式,集中计算,集中管理;客户机/服务器(Client/Server,简称C/S)模式,分布计算,分布管理;浏览器/服务器模式,利用Internet跨平台。端口号与IP地址的组合称为网络套接字(socket)。
Java语言在实现C/S模式中,套接字分为两类:在Server端,ServerSocket类支持底层的网络通信;在Client端,Socket类支持网络的底层通信。Server机通过端口(总线I/O地址)提供面向Client机的服务;Server 机在它的几个不同端口分别同时提供几种不同的服务。Client接入Server的某一端口,通过这个端口提请Server机为其服务。双方实现通信有流式socket和数据报式socket两种可选方式。 10.2 Java数据库编程基础
一个网络关系数据应用系统是一个三层次结构。
客户机与服务器采用网络连接;客户机端应用程序按通信协议与服务器端的数据库服务程序通信;数据库服务程序通过SQL命令与数据库管理系统通信。 10.2.1 Java程序与数据库连接
Java程序与数据库连接方法有两种。一种是使用JDBC?ODBC桥接器与数据库连接;另一种是用纯Java的JDBC驱动程序实现与数据库连接。 1.使用JDBC?ODBC桥接器与数据库连接 Java程序使用JDBC?ODBC桥接器与数据库连接,Java程序与数据库通信的过程是:先由数据库应用程序向 ODBC驱动管理器发出API调用,ODBC驱动管理器将这个调用转换成向数据库管理系统的ODBC驱动程序调用,数据库管理系统又将这个调用转换成对操作系统的数据输入/输出调用。最后,操作系统从数据库中得到实际数据逐级返回。 Java数据库连接JDBC(JavaDataBaseConnectivity)由一组用Java语言编写的类和接口组成,JDBC是Java程序与数据库连接的API。它能做以下三件事情:
与某个数据库建立连接、向数据库发送SQL语句和处理数据库返回的结果。 2.用纯Java的JDBC驱动程序实现与数据库连接
Java程序也可以用纯Java的JDBC驱动程序实现与数据库连接。这种方法应用较广泛,但是需要下载相应的驱动程序包,因为不同的数据库的连接代码可能不同,连接不同的数据库,加载的驱动程序也可能不相同。使用纯JavaJDBC驱动程序连接数据库的过程 如下:
(1)加载驱动程序。
(2)创建指定数据库的URL。 (3)建立连接。
10.2.2 几个重要的类和接口 1.DriverManager类
DriverManager类处理驱动程序的加载和建立新数据库连接。 2.Connection类
Connection类是java.sql包中用于处理与特定数据库连接的类。 3.Statement类
Statement类是java.sql包中用于在指定的连接中处理SQL语句的类。数据库编程的要点是在程序中嵌入SQL命令。程序需要声明和创建连接数据库的Con? nection对象,并让该对象连接数据库。调用类DriverManager的静态方法getConnection()获得Connection 对象,实现程序与数据库的连接。然后,用Statement类
声明SQL语句对象,并调用Connection对象的createStatement()方法,创建SQL语句对象。 4.ResultSet类
有了SQL语句对象后,调用语句对象的方法executeQuery()执行SQL语句查询,并将查询结果存放在一个用ResultSet类声明的对象中。ResultSet对象实际上是一个由查询结果数据构成的表,是一个管式数据集,由统一形式的数据行组成,一行对应一条查询记录。在ResultSet对象中隐含着一个游标,一次只能获得游标当前所指的数据行,用next方法可取下一个数据行。 ·39·第10章 网络与数据库编程基础
10.2.3 数据库查询
利用Connection对象的createStatement方法建立Statement对象,利用Statement对象的executeQuery()方法执行SQL查询语句进行查询,返回结果集,再利用形如getXXXX()的方法从结果集中读取数据。经过这样的一系列步骤就能实现对数据库的查询。 10.2.4 数据库更新
数据库更新操作包括数据表创建、删除,以及数据表记录的增加、删除、修改等操作。如果利用数据库的SQL命令实现,则利用Statement对象的executeUpdate ()的方法,执行SQL的update语句,实现数据表的修改;执行SQL的insert语句,实现数据表记录的添加。 1.插入数据表记录
插入数据表记录有3种方案。
(1)使用Statement对象实现插入数据表记录的SQL语句的语法是:
insertinto表名(字段名1,字段2,……)value(字段值1,字段值2,……)
(2)使用ResultSet对象
使用ResultSet对象的方法 moveToInsertRow()将数据表游针移到插入位置,输入数据后,用方法inser? tRow()插入记录。
(3)使用PrepareStatement对象
与使用Statement对象的方法类似,只是创建SQL语句时,暂时用参数?表示值,然后由SQL语句对象生成PrepareStatement对象,插入时通过设定实际参数,实现记录的更新。 2.修改数据表记录
修改数据表记录也有3种方案。 (1)使用Statement对象
实现修改数据表记录的SQL语句的语法是update表名set字段名1=字段值1,字段名2=字段值2,……where特定条件 (2)使用ResultSet对象
先建立ResultSet对象,然后直接设定记录的字段值,修改数据表的记录。 (3)使用PrepareStatement对象
创建SQL语句时,暂时用参数?表示值,然后由SQL语句对象生成PrepareStatement对象,接着通过设定实际参数实现记录的更新。 3.删除数据表记录 ·59·第10章 网络与数据库编程基础 删除数据表记录也有3种方案。 (1)使用Statement对象
删除数据表记录的SQL语句的语法是deletefrom表名where特定条件 (2)使用ResultSet对象
先创建一个SQL语句,然后调用Statement对象的executeUpdate()方法。
(3)使用PrepareStatement对象创建SQL语句时,暂时用参数?表示值,然后由
SQL语句对象生成PrepareStatement对象,接着通过设定实际参数实现特定记录的删除。