实验06多线程剖析_第1页
实验06多线程剖析_第2页
实验06多线程剖析_第3页
实验06多线程剖析_第4页
实验06多线程剖析_第5页
已阅读5页,还剩6页未读 继续免费阅读

付费下载

下载本文档

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

文档简介

实验六 TCPSocket中的多线程一、本实验目的及要求:1.理解进程和线程的概念;2.掌握JAVA中多线程技术,实现方法(继承 Thread类,或实现 Runnable接口);3.将多线程技术和 TCPSocket结合,在 TCPSocket中引用多线程技术,实现多用户实时通信;4.实验报告内容应包括,本实验的第三、四、五部分的答案,以及第六部分的程序后要求。二、基础知识每个正在系统上运行的程序都是一个进程(process)。每个进程包含一到多个线程(thread)。进程也可能是整个程序或者是部分程序的动态执行。线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。Java对多线程的支持是非常强大的,他屏蔽掉了许多的技术细节,让我们可以轻松的开发多线程的应用程序。 Java里面有 2个方法实现多线程,1 继承 Thread 类,比如class MyThread extends Thread {public void run() {这里写上线程的内容}public static void main(String[] args) {使用这个方法启动一个线程new MyThread().start();}}2 实现 Runnable 接口,例如class MyThread implements Runnable{public void run() {这里写上线程的内容}public static void main(String[] args) {使用这个方法启动一个线程new Thread(new MyThread()).start();}}一般鼓励使用第二种方法, 因为 Java里面只允许单一继承, 但允许实现多个接口。第二个方法更加灵活。三、基础知识填空1.程序的概念是( ),进程的概念是( ),线程的概念是()。2.线程的两种实现方法,分别是继承()和实现()接口。3.线程的四个状态分别是()、()(、)和()。Sleep是线程重要的方法其作用是()。4.在自定义线程是,必须要要重写()方法,通过()启动线程对象。5.为了避免多个线程共享一个资源而引起的冲突,在Java中提供了关键字()实现了资源锁,该关键字可以修饰方法也可以修饰程序段。四、程序填空采用继承Thread方法声明一个线程类publicclassmyThreadextends (publicmyThread( ){super(name);

){

//继承线程类//构造方法中的参数}publicvoid (){System.out.println("welcome");

//线程中运行的方法}publicstaticvoidmain(String[]args){myThreadmyT=newmyThread("

线程

1");myT. ();

//启动线程}}采用实现Runnable接口方法声明一个线程类publicclassmyThread implements(publicmyThread(Stringname){(name);

){}publicvoid (){System.out.println("welcome");}publicstaticvoidmain(String[]args){myThreadmyT=newmyThread("ThreadtMy=new.start();

线程1");(myT);}}2多线程累计器classSum{//共享资源,计数器

countintcount;

//共享资源publicintadd(){

//同步锁count=count+1;System.out.println("add:"+count);returncount;}}classSumThreadextendsThread{//定义线程privateSumsd;privateintsum=0;publicSumThread(Stringname,Sumsd){super(name);this.sd=sd;}publicvoidrun(){// 必需的重写try{for(inti=0;i<10;i++){sum+=sd.add();Thread.sleep( );}Thread.sleep(1000);}catch(Exceptione){}System.out.println(getName()+"累加和:"+sum);}publicintgetSum(){returnsum;}}publicclassSumDemo{publicstaticvoidmain(String[]args){Sumsd=newSum();//代表共享资源的变量SumThreadst1=newSumThread("线程1",sd);//创建完毕SumThreadst2=newSumThread("线程2",SumThreadst3=newSumThread("线程3",sd);st1. ;//使线程运行st2.start(); st3.start();st1. ; st2.join(); st3.join();

);System.out.println("总和为:"+(st1.getSum()+st2.getSum()+st3.getSum()));}}五、实验内容1.多线程累加示例。在本例中,实现

1-30

的累计,其中共享资源池为

1-30的数字的递增,采用了同步锁 synchronized。classSum{//共享资源,计数器privateintcount;//共享资源

countpublicintadd(){synchronized(this){//代码段1,共享锁,修饰程序段或者方法count=count+1;System.out.println("add:"+count);returncount;}}}classSumThreadimplementsRunnable{//定义线程privateSumsd;privateintsum=0;private int[]a=newint[10];publicSumThread(Stringname,Sumsd){super(name);this.sd=sd;}publicvoidrun(){// 必需的重写try{for(inti=0;i<10;i++){a[i]=sd.add();sum+=a[i];Thread.sleep(100);}Thread.sleep(1000);}catch(Exceptione){}System.out.println(getName()+"累加和:"+sum);}publicvoidshowData(){System.out.print(getName()+"获得的数为");for(inti=0;i<10;i++){if(i%10==0)System.out.println();System.out.print(a[i]+"+\t");}}publicintgetSum(){returnsum;}}publicclassSumDemo{publicstaticvoidmain(String[]args){Sumsd=newSum();//代表共享资源的变量SumThreads1=newSumThread("线程1",sd);//创建完毕SumThreads2=newSumThread("线程2",sd);SumThreads3=newSumThread("线程3",sd);Threadst1=newThread(s1);Threadst2=newThread(s2);Threadst3=newThread(s3);st1.setPriority(Thread.MAX_PRIORITY); //代码段2st2.setPriority(10);st3.setPriority(1);longbegin=System.currentTimeMillis();st1.start();//使线程运行st2.start(); st3.start();St1.join(); st2.join(); st3.join();st1.showData();st2.showData();st3.showData();System.out.println("总和为 :" +(st1.getSum() + st2.getSum()+st3.getSum()));longend=System.currentTimeMillis();System.out.println(“探测localhost的TCP端口,共耗时”+(end-begin)+"毫秒");} }报告内容:1.查看红色代码段1,观察保留synchronized和去掉,程序运行结果的变换;2.查看红色代码段2,为每个线程设置不同优先级,查看各线程所得到的结果;3.查找线程中方法 join的作用;4.修改程序为,可以实现 1-10000的累计,看 1个线程、10个线程和个线程完成累计所需要的时间差。2.采用多线程方式探测某主机上所有的import java.io.*;Import .*;classSum{//共享资源,计数器 countprivateintcount;//共享资源publicintadd(){synchronized(this){//代码段count=count+1;

TCP端口开放情况1,共享锁,修饰程序段或者方法System.out.println("add:"+count);returncount;}}}classScanThreadimplementsRunnable{//定义线程privateSumsd;privateintsum=0;privateStringhost;publicScanThread(Stringname,Sumsd,Stringhost){this.sd=sd;this.host=host;}publicvoidrun(){// 必需的重写intport;try{for(inti=0;i<65535;i++){port=sd.add();if(port>65535)break;try{Socketcs=newSocket(host,port);System.out.println("port"+port+" 出于开放状态 ");cs.close();}catch(Exceptione){System.err.println("port"+port+" 不能连接");}Thread.sleep(100);}Thread.sleep(1000);}catch(Exceptione){System.err.println("sleep

异常");}} }classScanDemo{publicstaticvoidmain(String[]args){Sumsd=newSum();//代表共享资源的变量ScanThreads1=newScanThread("线程1",sd,"localhost");//ScanThreads2=newScanThread("线程2",sd,"localhost");ScanThreads3=newScanThread("线程3",sd,"localhost");Threadst1=newThread(s1);Threadst2=newThread(s2);Threadst3=newThread(s3);try{

创建完毕longbegin=System.currentTimeMillis();st1.start();//使线程运行st2.start(); st3.start();st1.join(); st2.join(); st3.join();longend=System.currentTimeMillis();System.out.println(“探测localhost的TCP端口,共耗时 ”+(end-begin)+"毫秒");}catch(Exceptione){System.err.println(e.getMessage());}

}}报告内容:尝试增加更多的线程,查看测试效率结合Inetaddress探测主机所处局域网中所有计算机的

TCP

端口情况3.TCPSocket多线程通信importjava.io.*;import.*;importjava.util.*;@SuppressWarnings(value={"deprecation","unchecked"})publicclassMultiServerextendsThread{ServerSocketserverSocket=null;booleanlistening=true;intport=1080;intcount;publicMultiServer(){try{

//查阅该语句作用serverSocket=newServerSocket(port);System.out.println("TheChatServerislisteningon"+port);}catch(IOExceptione){System.err.println("Can'tlistenonPort");System.exit(1);}count=0;while(listening){try{newClientServiceThread(serverSocket.accept()).start();count+=1;System.out.println("TheChatServerget"+count+"Clients");}catch(IOExceptione){System.err.println("Can'tAccepttheClientConnectionApply");}}try{serverSocket.close();}catch(IOExceptione){System.exit(1);}this.start();}publicstaticvoidmain(Stringargs[]){MultiServerms=newMultiServer();}}classClientServiceThreadextendsThread{privateStringname="Client";privateSocketsocket=null;privateVectorclients=null;publicClientServiceThread(Socketsocket){super("ClientServiceThread");this.socket=socket;}publicClientServiceThread(Vectorclients,Socketsocket){super("ClientServiceThread");this.socket=socket;this.clients=clients;}publicvoidrun(){try{DataInputStreamin=newDataInputStream(newBufferedInputStream(socket.getInputStream()));PrintStreamout=newPrintStream(newBufferedOutputStream(socket.getOutputStream(),1024),true);StringinputLine,outputLine;GreetingProtocolgreeting=newGreetingProtocol();outputLine=cessInput(null);out.println("WelcometoMyChatServer, PleaseREGyourName,Format:name=yourname");out.flush();while((inputLine=in.readLine())!=null){System.out.println(+"Say:"+inputLine);if(inputLine.startsWith("name")){=inputLine.substring(inputLine.indexOf("=")+1);out.println("YourName"++"isREG");out.flush();}else{outputLine=cessInput(inputLine);out.println(outputLine);out.flush();}if(inputLine.equals("bye"))break;}out.close();in.close();socket.close();}catch(IOExceptione){e.printStackTrace();}}}报告内容:1)为该程序中,设置服务器最大的链接客户端数量,例如,最大数量为 50,当超过这个数字,服务器将主动拒绝新的客户端接入;2)测试,在你当前所使用计算机硬件环境下,所开设的服务器,可以最实现多少个客户端的链接;3)将该服务器类 有继承Thread,修改为实现 Runnable接口。在服务端使用Vector保存客户端信息,并转发信息给所有的客户端;为了保证消息的实时性,在客户端软件分别设立接受线程和发送线程。服务器端程序importjava.io.*;import.*;importjava.util.Vector;classMyServerimplementsRunnable{staticVector<Socket>clients=newVector();ServerSocketss=null;MyServer(intport){try{ss=newServerSocket(port); //端口号唯一标是本进程System.out.println("启动本地"+port+"端口");}catch(IOExceptione){System.err.println("启动本地"+port+"端口失败");System.exit(1);}}publicvoidrun(){Socketcs=null;try{while(true){cs=ss.accept();clients.add(cs);clientThreadct=newclientThread(cs);Threadtct=newThread(ct);tct.start();}}catch(IOExceptione){System.err.println(e.toString());}}classclientThreadimplementsRunnable{Socketcs=null;clientThread(Socketcs){this.cs=cs;}publicvoidrun(){StringinputStr,outputStr;try{DataOutputStreamos=newDataOutputStream(cs.getOutputStream());DataInputStreamis=newDataInputStream(cs.getInputStream());DataOutputStreamcos=null;os.writeUTF("WelcometoMyChatServer");os.flush();//立即将数据从输出缓存提交给网络发送while((inputStr=is.readUTF())!=null){System.out.println("Customer:"+inputStr);outputStr=inputStr; //将接收到的信息转发出去for(Socketc:clients){cos=newDataOutputStream(c.getOutputStream());cos.writeUTF(outputStr);cos.flush();}}os.close(); //流关闭is.close();cs.close(); //套接字关闭}catch(IOExceptione){System.err.println(e.getMessage());}}}publicstaticvoidmain(String[]args){MyServerms=newMyServer(8000);Threadtms=newThread(ms);tms.start();}}报告内容:添加方法可以打印出所有客户端的 Socket信息,并判断注册的用户名是否重复;客户端程序importjava.io.*;import.*;classexp_clientimplementsRunnable{Socketcs=null;StringhostName="localhost";intport=8000;DataInputStreamis =null;DataOutputStreamos=null;DataInputStreamstdIn=null;exp_client(StringhostName,intport){this.hostName=hostName;this.port=port;}publicvoidrun(){try{cs=newSocket(hostName,port);is=newDataInputStream(cs.getInputStream());os=newDataOutputStream(cs.getOutputStream());stdIn= newDataInputStream(System.in);System.out.println("客户端");os.writeUTF("你好服务器!");os.flush();newrcThread(cs).start();newscThread(

温馨提示

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

评论

0/150

提交评论