Java程序设计应用开发教程 课件 单元7 网络编程与多线程_第1页
Java程序设计应用开发教程 课件 单元7 网络编程与多线程_第2页
Java程序设计应用开发教程 课件 单元7 网络编程与多线程_第3页
Java程序设计应用开发教程 课件 单元7 网络编程与多线程_第4页
Java程序设计应用开发教程 课件 单元7 网络编程与多线程_第5页
已阅读5页,还剩28页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

单元7

网络编程与多线程7.1网络编程程序设计

任务7.1单用户登录任务描述用户登录KFID自动出货管理系统,需要在服务器与客户端之间进行通信,效果如图7-1所示。当第一个客户(即用户)登录系统时,从客户端发起登录请求,客户端将数据传递到服务器,由服务器显示用户登录信息,并响应给客户端登录信息的情况;当第一个客户与服务器进行通信时,其他客户必须等待,只有第一个客户退出,服务器才能与下一个客户进行通信,以此类推。图7-1单用户登录服务器客户端知识目标了解IP地址和TCP协议。理解InetAddress类。能力目标能接收和发送Socket信息。能使用I/O流套接字进行数据传输。素养目标培养人文精神和法治意识。培养严谨的工作作风和创新精神。任务7.1单用户登录当一台计算机向另一台计算机通信时,需要知道另一台计算机的地址。

互联网协议(InternetProtocol,简称:IP)地址可以用来唯一标识互联网上的计算机。IP地址就好像门牌号码,可以指定特定的地方,就像是“致能大道1号”。IPV4是由4个字节组成,也就是分为4个8位的二进制,每8位之间用点隔开,每个8位整数可以转换成一个0~255的十进制整数。IPV6是由16个字节(128位)组成,写成8个无符号整数,每个整数用4个16进制位表示,整数之间用冒号(:)分开,如3ffe:3201:1401:1280:c8ff:fe4d:db39:1984。IP地址有两种分类方式:IPV4和IPV6。IP地址映射被称为域名(domainname)

相关知识TCP协议互联网协议是在互联网中从一台计算机向另一台计算机以包的形式传输数据的一种低层协议。传输协议(TransmisssionControlProtocol,TCP)和用户数据报协议(UserDatagramProtocol,UDP)。TCP协议能够让两台主机建立连接并交换数据流。它确保数据的传送,也可确保数据包以它们发送的顺序传送。TCP端口是一个16位的整数,用来指定正在计算机上运行的进程(或程序),也就是表示数据信息由哪个程序的服务器处理,它能够让用户连接到服务器上各种不同的应用程序。不同的进程有不同的端口号,端口号可以从0~65535,从0~1023的端口号是保留给HTTP、FTP、SMTP等。如网页服务器(HTTP)的端口号是80,InetAddress类是Java对IP地址的封装,在中有许多类都使用到了InetAddress,包括ServerSocket,Socket,DatagramSocket等等。InetAddress类InetAddress类方法方法说明publicstaticInetAddress[]getAllByName(Stringhost)该方法可以从DNS上得到域名对应的所有的IP。这个方法返回一个InetAddress类型的数组。publicstaticInetAddressgetByAddress(byte[]addr)该方法获得网络主机中具有指导IP地址的InetAddress对象。publicstaticInetAddressgetByAddress(Stringhost,byte[]addr)该方法通过IP地址来创建InetAddress对象,而且IP地址必须是byte数组形式,host只是一个用于表示addr的别名publicstaticInetAddressgetByName(Stringhost)该方法以通过指定域名从DNS中得到相应的IP地址publicstaticInetAddressgetLocalHost()该方法可以得到描述本机IP的InetAddress对象示例:获取本地主机的域名与IP地址import.InetAddress;public

classAddress{public

static

voidmain(String[]args){InetAddressinetAddr=null;//创建一个InetAddress对象try{ inetAddr=InetAddress.getLocalHost();//实例化InetAddress对象Stringcanonical=

inetAddr.getCanonicalHostName();//获得本地主机的域名

StringhostName=inetAddr.getHostName();//获得主机名Stringaddress=

inetAddr.getHostAddress();//获得本机的IP地址

System.out.println("域名:"+canonical);System.out.println("主机名:"+hostName);System.out.println("IP地址:"+address);}catch(Exceptione){e.printStackTrace();}

}}Socket类.Socket类代表客户端和服务器都用来互相沟通的套接字。客户端要获取一个Socket对象通过实例化,而服务器获得一个Socket对象则通过accept()方法的返回值。Socket类构造方法构造方法说明publicSocket(Stringhost,intport)throwsUnknownHostException,IOException创建一个流套接字并将其连接到指定主机上的指定端口号publicSocket(InetAddresshost,intport)throwsIOException创建一个流套接字并将其连接到指定IP地址的指定端口号。publicSocket(Stringhost,intport,InetAddresslocalAddress,intlocalPort)throwsIOException创建一个套接字并将其连接到指定远程主机上的指定远程端口。publicSocket(InetAddresshost,intport,InetAddresslocalAddress,intlocalPort)throwsIOException创建一个套接字并将其连接到指定远程地址上的指定远程端口publicSocket()通过系统默认类型的SocketImpl创建未连接套接字Socket类Socket类的常用方法方法说明publicvoidconnect(SocketAddresshost,inttimeout)throwsIOException将此套接字连接到服务器,并指定一个超时值。publicInetAddressgetInetAddress()返回套接字连接的地址publicintgetPort()返回此套接字连接到的远程端口。publicintgetLocalPort()返回此套接字绑定到的本地端口。publicSocketAddressgetRemoteSocketAddress()返回此套接字连接的端点的地址,如果未连接则返回null。publicInputStreamgetInputStream()throwsIOException返回此套接字的输入流publicOutputStreamgetOutputStream()throwsIOException返回此套接字的输出流。publicvoidclose()throwsIOException关闭此套接字ServerSocket类服务器应用程序通过使用.ServerSocket类以获取一个端口,并且侦听客户端请求。ServerSocket类构造方法构造方法说明publicServerSocket(intport)throwsIOException创建绑定到特定端口的服务器套接字。publicServerSocket(intport,intbacklog)throwsIOException利用指定的backlog创建服务器套接字并将其绑定到指定的本地端口号。publicServerSocket(intport,intbacklog,InetAddressaddress)throwsIOException使用指定的端口、侦听backlog和要绑定到的本地IP地址创建服务器。publicServerSocket()throwsIOException创建非绑定服务器套接字。ServerSocket类ServerSocket类的常用方法方法说明publicintgetLocalPort()返回此套接字在其上侦听的端口。publicSocketaccept()throwsIOException侦听并接受到此套接字的连接。publicvoidsetSoTimeout(inttimeout)通过指定超时值启用/禁用SO_TIMEOUT,以毫秒为单位。publicvoidbind(SocketAddresshost,intbacklog)将ServerSocket绑定到特定地址(IP地址和端口号)。使用Socket实现网络通信连接

建立socket连接来连接服务器。传送

用户发送信息到服务器。接受

用户从服务器接受信息。要使客户端能够正常工作,必须要做好3个任务:案例:服务器程序与客户端一对一通信编写一个客户端程序和一个服务器程序,服务器端只向客户端输出“Helloworld”。分析:服务器程序(HelloServer.java)第一步:声明一个ServerSocket对象,声明一个PrintWriter对象,用于向客户端打印输出。ServerSocketserversocket=null;PrintWriterout=null;第二步:实例化ServerSocket对象,在9999端口进行监听。

serversocket=newServerSocket(9999);第三步:声明一个Socket对象clientsocket,此对象用于接收客户端的Socket连接。然后通过ServerSocket类中的accept()方法,接收客户端的Socket请求,此方法返回一个客户端的Socket请求。

clientsocket=serversocket.accept();第四步:通过客户端的Socket对象去实例化PrintWriter对象,此时out对象具备向客户端打印信息的能力。调用println()方法,将信息打印至客户端。out=newPrintWriter(clientsocket.getOutputStream(),true);out.println("Helloworld");第五步:分别关闭客户端Socket连接,服务器端Socket连接。

clientsocket.close();serversocket.close();案例:服务器程序与客户端一对一通信客户端程序(HelloClient.java)第一步:声明一个Socket对象,声明一个BufferedReader对象in,此对象用于读取服务器发送过来的数据。

Sockethellosocket=null;BufferedReaderin=null;第二步:用输入输出流与Socket关联。首先实例化hellosocket对象,此连接在本机的9999端口上监听。然后通过hellosocket对象实例化BufferedReader对象。hellosocket=newSocket("localhost",9999);in=newBufferedReader(newInputStreamReader(hellosocket.getInputStream()));第三步:等待服务器端发送过来的信息并打印。System.out.println(in.readLine());第四步:关闭BufferedReader对象;关闭Socket对象。in.close();hellosocket.close();如果要需要服务器与多个客户端通信,如何实现呢?可以通过线程来处理不同客户发送的信息。单元7

网络编程与多线程7.2多线程程序设计

任务7.2多用户登录任务描述多个用户登录自动出货管理系统,需要在服务器与多个客户端之间进行通信,效果如图7-2所示。多线程是Java的一个重要特性。在服务器启用多线程模式时,可以通过线程来处理不同用户发送的信息。当每个用户登录时,从客户端发起登录请求,将登录用户数据传递到服务器,由服务器显示用户登录信息,并将信息响应给客户端(登录成功或登录失败)。当有多个客户端连接到服务器时,服务器会为每个客户端建立一个线程来处理接收到信息,而不会产生阻塞,实现一个服务器与多个客户端的通信。图7-2多用户登录知识目标了解线程与进程的区别。熟悉实现多线程的方法。熟悉线程同步的方法。能力目标能通过继承Thread类实现多线程。能通过Runnable接口实现多线程。能使用方法或代码块实现线程同步。能使用多线程和套接字实现服务器服务多个客户的操作。素养目标良好的职业道德规范。培养严谨的工作作风和创新精神。任务7.2多用户登录在高速公路收费匝道上,经常会看到排成长龙的车队。如果让你来缓解这一拥塞的交通状况,你的方案是什么?在一个行政收费大厅里,如果只有一个办事窗ロ,等待办事的客户很多。解决方案是?进程可以理解为一个应用程序的执行过程,应用程序一旦执行,就是一个进程。如果把进程比作一个收费站,多个收费匝道就可以比作线程。如果将行政大厅比喻为一个进程,每个办事窗口就是一个线程。

相关知识多线程:多线程在Windows操作系统中的运行进程1进程3线程1线程3线程2线程5线程4线程n…进程2在CPU执行进程2的时间片内图7-3多线程在Windows操作系统中的运行模式Windows操作系统是多任务操作系统,它以进程为单位。每个独立执行的程序都被称为进程。比如:正在运行的QQ是一个进程、正在运行的企业微信是一个进程,正在运行的Eclipse也是一个进程,每个进程都可以包含多个线程。系统可以分配给每个进程一段使用CPU的时间(也可以称为CPU时间片),CPU在这段时间中执行某个进程(同理,同一个进程种每个线程也可以得到一小段执行时间,这样一个进程就可以具有多个并非执行的线程),然后下一个CPU时间片又执行另一个进程。进程是并发执行程序在执行过程中资源分配和管理的基本单位(资源分配的最小单位),每个进程都有自己独立的地址空间。线程是比进程更小的执行单元,是进程中的一个实体,是被系统独立调度和分派的基本单位。一个进程在执行过程中,可以产生多个线程。同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。多线程的机制则指可以同时运行多个程序块(进程的多条路径),在Java中被称为并发机制。采用多线程机制可以是计算机资源得到更充分的使用,多线程可以使程序在同一时间内完成很多任务操作。进程与线程的概念classTestThread{

public

voidrun(){

for(int

i=0;i<5;++i){System.out.println("TestThread在运行"

);

}

}}public

classMainClass{public

static

voidmain(Stringargs[]){

newTestThread().run();//创建一个新线程对象,并输出

//循环输出

for(int

i=0;i<5;++i){System.out.println("main线程在运行"

);

}

}}引入:单一线程的运行流程要想运行main()方法中的for循环,必须等ThreadDemo类中的run()方法执行完。即使该代码块不依赖前面的代码块的计算机结果,它也“无可奈何”地必须等待,这就是单一线程的缺陷。如何使两个代码块能否交替输出呢?答案是肯定的,就是Java多线程的作用了。Thread类的构造方法

publicThread():

创建一个新的线程对象

publicThread(StringthreadName):创建一个名称为threadName的线程对象Thread类的常用方法Interrupt():中断线程

run():如果该线程是使用独立的Runnable对象构造的,则调用Runnable对象的run()方法,否则,该方法不执行任何操作并返回。start():使该线程开始执行,Java虚拟机调用该线程的run()方法。sleep():在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)继承java.lang.Thread类Thread类是Java.lang包中的一个类,Thread类的对象用来代表线程实现多线程的方法:通过继承Thread类创建、启动并执行一个线程的步骤如下:创建一个继承Thread类的子类覆写Thread类的run()方法。创建线程类的一个对象。通过线程类的对象调用start()方法启动线程(启动之后会自动调用覆写的run()方法执行线程)继承java.lang.Thread类继承java.lang.Thread类public

classThreadDemoTestextendsThread{privateStringname;

publicThreadDemoTest(Stringname){

this.name=name;

}

//重写run()方法

public

voidrun(){

for(int

i=0;i<5;i++){System.out.println(name+"运行:"

+i);

try{

sleep((int)Math.random()*10);//正在执行线程休眠}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}public

static

voidmain(String[]args){ThreadDemoTestt1=newThreadDemoTest("A"

);//创建线程对象t1ThreadDemoTestt2=newThreadDemoTest("B"

);//创建线程对象t2t1.start();//启动线程t1t2.start();//启动线程t2}}所有的线程对象都必须是Thread或者其子类的实例。创建一个新的线程t1,

此线程进入新建状态;调用start()方法使得线程进入就绪状态使用继承Thread类的子类来创建线程类时,多个线程无法共享线程类的实例变量实现java.lang.Runnable接口如果当前类不仅要继承其他类(非Thread类),还要实现多线程,那么如何处理呢?使用Runnable接口启动新线程

创建Runnable对象;使用参数为Runnable对象的构造方法创建Thread对象;调用start()方法启动线程。Thread对象Runnable

对象启动线程,执行run()方法中的代码。根据Runnable对象创建Thread对象调用start()方法实现Runnable接口创建线程的流程实现java.lang.Runnable接口classRunnableThreadDemoimplementsRunnable{

public

voidrun(){

for(int

i=0;i<5;i++){System.out.println(Thread.currentThread().getName()

+"运行"+i);

try{

Thread.sleep(1000);//睡眠1秒}catch(InterruptedExceptione){

e.printStackTrace();

}

}

}}public

classRunnableThread{public

static

voidmain(Stringargs[]){

RunnableThreadDemo

th=newRunnableThreadDemo();

newThread(th).start();//使用Thread类的start方法启动线程

for(int

i=0;i<5;i++){System.out.println("main线程在运行"

);

try{

Thread.sleep(1000);//睡眠1秒}catch(InterruptedExceptione){

e.printStackTrace();}

}

}}静态方法currentThread(),返回值是当前正在执行该方法的线程实例。显示Runnable接口相对于继承Thread类显著优势:避免了由于Java的单继承特性带来的局限性。可是多个线程共享相同的资源,以达到资源共享的目的。线程生命周期及状态线程具有生命周期,其中包含5种状态,分别为新建状态、就绪状态、运行状态、暂停状态(包含休眠、等待和阻塞)和死亡状态。Thread.sleep()方法Object.wait()方法Object.notify()Object.join()方法Thread.yield()案例:交通红绿灯根据所给代码,补充完整,实现多线程在模拟红绿灯变化场景。多线程的同步如何解决资源共享的问题?共享资源加锁所有解决多线程资源冲突问题的方法,都是在给定时间只允许一个线程访问共享资源,相当于给共享资源加道锁。使用代码块实现线程同步使用方法实现线程同步多线程的同步使用代码块实现线程同步同步机制使用synchronized关键。每个Java对象都有一个内置锁,如果代码块使用synchronized关键字进行声明,通过锁定指定的对象,来对同步块中包含的代码进行同步,则使用该关键字的代码块称为同步块,也称为临界区。synchronized(Object)同步代码与同步方法锁的是对象,而不是代码。如果某个对象被同步代码块或同步方法锁住了,那么其他使用该对象的代码必须等待,直到该对象的锁被释放。public

classSynchronizedTestimplementsRunnable{int

num

=10;//设置当前总票数public

voidrun(){while(true){//设置无限循环synchronized(this){//设置同步代码块if(num>0){//判断当前票数是否大于0try{Thread.sleep(100);//使当前线程休眠100毫秒}catch(Exceptione){e.printStackTrace();}System.out.println(Thread.currentThread().getName()+“---票数"

+num--;}}}}public

static

voidmain(String[]args){SynchronizedTestt=newSynchronizedTest();ThreadtA=newThread(t,"线程1");ThreadtB=newThread(

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论