实验六TCPSocket中的多线程一、本实验目的及要求:1.理解进程和线程的概念;2.掌握JAVA中多线程技术,实现方法(继承Thread类,或实现Runnable接口);3.将多线程技术和TCPSocket结合,在TCPSocket中引用多线程技术,实现多用户实时通信;4.实验报告内容应包括,本实验的第三、四、五部分的答案,以及第六部分的程序后要求。二、基础知识每个正在系统上运行的程序都是一个进程(process)。每个进程包含一到多个线程(thread)。进程也可能是整个程序或者是部分程序的动态执行。线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。也可以把它理解为代码运行的上下文。所以线程基本上是轻量级的进程,它负责在单个程序里执行多任务。Java对多线程的支持是非常强大的,他屏蔽掉了许多的技术细节,让我们可以轻松的开发多线程的应用程序。Java里面有2个方法实现多线程,1继承Thread类,比如classMyThreadextendsThread{publicvoidrun(){//这里写上线程的内容}publicstaticvoidmain(String[]args){//使用这个方法启动一个线程newMyThread().start();}}2实现Runnable接口,例如classMyThreadimplementsRunnable{publicvoidrun(){//这里写上线程的内容}publicstaticvoidmain(String[]args){//使用这个方法启动一个线程newThread(newMyThread()).start();}}一般鼓励使用第二种方法,因为Java里面只允许单一继承,但允许实现多个接口。第二个方法更加灵活。三、基础知识填空1.程序的概念是(),进程的概念是(),线程的概念是()。2.线程的两种实现方法,分别是继承()和实现()接口。3.线程的四个状态分别是()、()、()和()。Sleep是线程重要的方法其作用是()。4.在自定义线程是,必须要要重写()方法,通过()启动线程对象。5.为了避免多个线程共享一个资源而引起的冲突,在Java中提供了关键字()实现了资源锁,该关键字可以修饰方法也可以修饰程序段。四、程序填空1.采用继承Thread方法声明一个线程类publicclassmyThreadextends(){//继承线程类publicmyThread(){//构造方法中的参数super(name);}publicvoid(){//线程中运行的方法System.out.println(welcome);}publicstaticvoidmain(String[]args){myThreadmyT=newmyThread(线程1);myT.();//启动线程}}2.采用实现Runnable接口方法声明一个线程类publicclassmyThreadimplements(){publicmyThread(Stringname){(name);}publicvoid(){System.out.println(welcome);}publicstaticvoidmain(String[]args){myThreadmyT=newmyThread(线程1);ThreadtMy=new(myT);.start();}}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;i10;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{//共享资源,计数器countprivateintcount;//共享资源publicintadd(){synchronized(this){//代码段1,共享锁,修饰程序段或者方法count=count+1;System.out.println(add:+count);returncount;}}}classSumThreadimplementsRunnable{//定义线程privateSumsd;privateintsum=0;privateint[]a=newint[10];publicSumThread(Stringname,Sumsd){super(name);this.sd=sd;}publicvoidrun(){//必需的重写try{for(inti=0;i10;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;i10;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个线程和100个线程完成累计所需要的时间差。2.采用多线程方式探测某主机上所有的TCP端口开放情况importjava.io.*;Importjava.net.*;classSum{//共享资源,计数器countprivateintcount;//共享资源publicintadd(){synchronized(this){//代码段1,共享锁,修饰程序段或者方法count=count+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;i65535;i++){port=sd.add();if(port65535)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探测主机所处局域网中所有计算机的TC