JAVA入门学习实例
来源:互联网 发布:上瘾网络剧未剪版 编辑:程序博客网 时间:2024/06/13 23:23
Java面向对象中类与对象的概念和使用
构造方法的主要作用 一是用来实例化该类。二是 让该类实例化的时候执行哪些方法,初始化哪些属性。当一个类声明了构造函数以后,JVM 是不会再给该类分配默认的构造函数。
构造方法是一种特殊的方法,具有以下特点。
(1)构造方法的方法名必须与类名相同。
(2)构造方法没有返回类型,也不能定义为void,在方法名前面不声明方法类型。
(3)构造方法的主要作用是完成对象的初始化工作,它能够把定义对象时的参数传给对象的域。
(4)构造方法不能由编程人员调用,而要系统调用。
(5)一个类可以定义多个构造方法,如果在定义类时没有定义构造方法,则编译系统会自动插入一个无参数的默认构造器,这个构造器不执行任何代码。
(6)构造方法可以重载,以参数的个数,类型,或排列顺序区分
重载与重写:
重载是在同一个类中的两个或两个以上的方法,拥有相同的方法名,但是参数却不相同,方法体也不相同,最常见的重载的例子就是类的构造函数
重写是子类的方法覆盖父类的方法,发生在继承中,要求方法名,参数类型和返回值都相同。被重写的方法不能拥有比父类更严格的权限(public>protected>default>private)
package test;class Person{ String name; int age; public Person(String name,int age){ //构造方法 this.name=name; this.age=age; } public Person(String name){ //方法重载,对参数类型或个数,权限均无要求 this.name=name; System.out.println(name); } public void tell(){ System.out.println(name +":" + age); }}public class zlk { public static void main(String[] args) { Person p =new Person("zhang",17); p.tell(); Person q =new Person("Li"); }}
Java面向对象的基本特征之封装性
封装就是隐藏实现细节,将属性私有化,提供公有方法访问私有属性。
package test;class Person{ private String name; private int age; //将类的成员变量声明为private public void setName(String name) { //通过public的方法对变量进行访问 this.name = name; //一般定义两个方法实现这两种操作,即:setxx()与getxx() } public String getName() { return name; } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void tell(){ System.out.println(getName() +":" + getAge()); }}public class zlk { public static void main(String[] args) { Person p =new Person(); p.setName("Zhang"); p.setAge(17); p.tell(); }}
Java面向对象基本特征之继承
JAVA只支持单继承,一个类只能有一个父类,同时一个类可以实现多个接口,从而克服单继承的缺点。
子类不能直接访问父类private成员,可用set,get方法;
子对象的实例化过程先调用父类的构造方法,在调用子类的构造方法;
子类重写父类方法之后(方法名称,返回类型,参数都相同),不能拥有比父类更严格的访问权限(public>protected>default>private)
Super关键字强行执行父类方法
继承: class 子类 extends 父类{}
package test;class Person{ private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } Person(int n){ //有参数的构造方法 System.out.println("Person() constructor is called !"); }}class Student extends Person{ //继承 private int score; public int getScore() { return score; } public void setScore(int score) { this.score = score; } public void tell(){ System.out.println(getName() +": 得分"+getScore()); } Student(){ //构造方法的继承 super(200);//构造方法先引用父类的构造方法,编译器找不到无参方法就报错.必须在子类构造方法最上面加一句super(int值)才可以通过编译. System.out.println("Student() constructor is called !"); }}public class zlk { public static void main(String[] args) { Student s= new Student(); s.setName("Zhang"); s.setScore(100); s.tell();} }
Java面向对象基本特征之多态
什么是多态
面向对象的三大特性:封装、继承、多态。从一定角度来看,封装和继承几乎都是为多态而准备的。这是我们最后一个概念,也是最重要的知识点。
多态的定义:指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用)
实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
多态的作用:消除类型之间的耦合关系。
现实中,关于多态的例子不胜枚举。比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是 Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
下面是多态存在的三个必要条件,要求大家做梦时都能背出来!
多态存在的三个必要条件!
一、要有继承;
二、要有重写;
三、父类引用指向子类对象。
多态的好处:
1.可替换性(substitutability)。多态对已存在代码具有可替换性。例如,多态对圆Circle类工作,对其他任何圆形几何体,如圆环,也同样工作。
2.可扩充性(extensibility)。多态对代码具有可扩充性。增加新的子类不影响已存在类的多态性、继承性,以及其他特性的运行和操作。实际上新加子类更容易获得多态功能。例如,在实现了圆锥、半圆锥以及半球体的多态基础上,很容易增添球体类的多态性。
3.接口性(interface-ability)。多态是超类通过方法签名,向子类提供了一个共同接口,由子类来完善或者覆盖它而实现的。如超类Shape规定了两个实现多态的接口方法,computeArea()以及computeVolume()。子类,如Circle和Sphere为了实现多态,完善或者覆盖这两个接口方法。
4.灵活性(flexibility)。它在应用中体现了灵活多样的操作,提高了使用效率。
5.简化性(simplicity)。多态简化对应用软件的代码编写和修改过程,尤其在处理大量对象的运算和操作时,这个特点尤为突出和重要。
Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。
package test;//父类 class Father{ //父类有一个打孩子方法 public void hitChild(){} } //子类1 class Son1 extends Father{ //重写父类打孩子方法 public void hitChild(){ System.out.println("为什么打我?我做错什么了!"); } } //子类2 class Son2 extends Father{ //重写父类打孩子方法 public void hitChild(){ System.out.println("我知道错了,别打了!"); } } //子类3 class Son3 extends Father{ //重写父类打孩子方法 public void hitChild(){ System.out.println("我跑,你打不着!"); } } //测试类 public class zlk{ public static void main(String args[]){ Father father; father = new Son1(); father.hitChild(); father = new Son2(); father.hitChild(); father = new Son3(); father.hitChild(); } }
Java面向对象-抽象类与接口
抽象类的特点:
1:包含一个抽象方法的类,抽象类和抽象方法必须由abstract关键字修饰(可以描述类和方法,不可以描述变量)。
2:抽象方法只定义方法声明,并不定义方法实现。
3:抽象类不可以被创建对象(实例化)。
4:只有通过子类继承抽象类并覆盖了抽象类中的所有抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。子类必须重写抽象类中的所有抽象方法!
抽象类定义格式: abstract class className{属性;方法;抽象方法}
package test;abstract class Person{ private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } public abstract void tell(); public abstract void say();}class Student extends Person{ public void tell(){ System.out.println(getName()); } public void say(){}; //子类必须重写抽象类中的所有抽象方法!}public class zlk { public static void main(String[] args) { Student s= new Student(); s.setName("Zhang"); s.tell();}}
接 口:
1:是用关键字interface定义的特殊的类。里面全部由全局常量和公共的抽象方法组成。
interface Inter{ 全局常量:public static final 抽象方法:public abstract}
2:接口中有抽象方法,说明接口不可以实例化。接口的子类必须实现了接口中所有的抽象方法后,该子类才可以实例化。否则,该子类还是一个抽象类。子类必须重写抽象类中的所有抽象方法!
3:类与类之间存在着继承关系,类与接口中间存在的是实现关系。
继承用extends ;实现用implements ;
4:接口和类不一样的地方,就是,接口可以被多实现,这就是多继承改良后的结果。java将多继承机制通过多实来体现。
5:一个类在继承另一个类的同时,还可以实现多个接口。所以接口的出现避免了单继承的局限性。还可以将类进行功能的扩展。
package test;interface Inter1{ public static final int num1=1; public abstract void tell();}interface Inter2{ public static final int num2=2; public abstract void say();}//一个接口通过extends关键字同时继承多个接口interface Inter3 extends Inter1,Inter2{ public static final int num3=3; public abstract void call();} abstract class Abs{ public abstract void print(); }//通过子类实现接口class A implements Inter1{ public void tell(){ System.out.println("A实现了接口"+num1); }}//通过子类继承抽象类同时实现接口class B extends Abs implements Inter1,Inter3{ public void tell(){}; public void say(){}; public void call(){ System.out.println("INter3继承了接口"+num1+","+num2); } public void print(){ System.out.println("B继承抽象类Abs并实现了接口"+num1+","+num3); }}public class zlk { public static void main(String[] args) { A a=new A(); a.tell(); B b=new B(); b.call(); b.print();}}
Java面向对象-泛型
泛型是Java SE1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 Java语言引入泛型的好处是安全简单。
泛型类:
package test;public class zlk<T> { //在类名后面添加了类型参数声明部分 private T t; public void add(T t) { this.t = t; } public T get() { return t; } public static void main(String[] args) { zlk<Integer> integerBox = new zlk<Integer>();//对象创建:在类名后面添加具体类型 zlk<String> stringBox = new zlk<String>(); integerBox.add(new Integer(10)); stringBox.add(new String("Hello World")); System.out.printf("Integer Value :%d\n\n", integerBox.get()); System.out.printf("String Value :%s\n", stringBox.get()); } }
泛型方法将数组排序输出:
package test;import java.util.Arrays;public class zlk{ // 泛型方法 printArray public static < E > void printArray( E[] inputArray ) { //排序 Arrays.sort(inputArray); // 输出数组元素 for ( E element : inputArray ){ System.out.printf( "%s ", element ); } System.out.println(); } public static void main( String args[] ) { // 创建不同类型数组: Integer, Double 和 Character Integer[] intArray = { 1, 5, 3, 2, 5 }; Double[] doubleArray = { 3.3, 2.2, 1.1, 4.4 }; Character[] charArray = { 'C', 'A', 'E', 'B', 'D' }; System.out.println( "Array integerArray contains:" ); printArray( intArray ); // 传递一个整型数组 System.out.println( "\nArray doubleArray contains:" ); printArray( doubleArray ); // 传递一个双精度型数组 System.out.println( "\nArray characterArray contains:" ); printArray( charArray ); // 传递一个字符型型数组 } }
Java集合类详解
Collection集合类的基本结构:
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map (key—-> value)
├Hashtable
├HashMap
└WeakHashMap
1、Collection接口
Collection是最基本集合接口,它定义了一组允许重复的对象。Collection接口派生了两个子接口Set和List,分别定义了两种不同的存储方式。
2、 Set接口
Set接口继承于Collection接口,它没有提供额外的方法, Set接口的集合类中的元素是不可重复的。但是可以排序。
两个常用子类:
1.散列存放:HashSet;
2.有序存放:TreeSet;
3、 List接口
List接口同样也继承于Collection接口,但是与Set接口恰恰相反,List接口的集合类中的元素是对象有序且可重复。
特征:有序且可重复。
两个重要的实现类:ArrayList和LinkedList
1.ArrayList特点是有序可重复的
2.LinkedList是一个双向链表结构的。
4、Map接口
Map也是接口,但没有继承Collection接口。该接口描述了从不重复的键到值的映射。Map接口用于维护键/值对(key/value pairs)。
特征:它描述了从不重复的键到值的映射。
两个重要的实现类:HashMap和TreeMap
1.HashMap,中文叫散列表,基于哈希表实现,特点就是键值对的映射关系。一个key对应一个Value。HashMap中元素无序存放,Key不允许重复。更加适合于对元素进行插入、删除和定位。
2.TreeMap,基于红黑书实现。TreeMap中的元素保持着某种固定的顺序。更加适合于对元素的顺序遍历。
5、Iterator接口
Iterator接口,在C#里有例外一种说法IEnumerator,他们都是集合访问器,用于循环访问集合中的对象。所有实现了Collection接口的容器类都有iterator方法,用于返回一个实现了Iterator接口的对象。Iterator对象称作迭代器,Iterator接口方法能以迭代方式逐个访问集合中各个元素,并可以从Collection中除去适当的元素。
6、Comparable接口
Comparable可以用于比较的实现,实现了Comparable接口的类可以通过实现comparaTo方法从而确定该类对象的排序方式。
List接口,Iterator接口:
package test; import java.util.ArrayList; import java.util.Iterator; import java.util.List; public class zlk { public static void main(String[] args) { List<String> list = new ArrayList<String>(); //添加元素 list.add("aaa"); list.add("bbb"); list.add("ccc"); list.add("ddd"); list.add(null); //遍历 for (String string : list) { System.out.println(string); } System.out.println("---------------"); //修改 list.set(1, "bbb2"); //删除 list.remove("ccc"); //迭代器遍历 Iterator<String> iterator = list.iterator(); while(iterator.hasNext()){ System.out.println(iterator.next()); } System.out.println("--------------"); list.clear(); //清空列表 System.out.println("清空后list的大小"+list.size());//打印大小 List<String> list2 = new ArrayList<String>(); list2.add("a"); list2.add("b"); //将list2添加到list中 list.addAll(list2); //遍历 for (String string : list) { System.out.println(string); } } }
HashMap接口,set,collection,Iterator接口:
package test;import java.util.*;public class zlk { public static void main(String[] args) {Map<String,String> map=new HashMap<String,String>();map.put("1","A");map.put("2.5","B");map.put("123L","C");String str=map.get("1");System.out.println(str);System.out.println(map.size());System.out.println(map.containsKey("2.5"));System.out.println(map.containsValue("D")); //输出所有key Set<String> s=map.keySet(); Iterator<String> i=s.iterator(); while(i.hasNext()){ System.out.println(i.next()); } //输出所有value Collection<String> c=map.values(); Iterator<String> j=c.iterator(); while(j.hasNext()){ System.out.println(j.next()); }}}
Java本地文件操作
File类操作:
package test;import java.io.*;public class zlk { public static void main(String[] args) { File folder = new File("F:\\Hello"); folder.mkdirs(); //创建文件夹 System.out.println("文件夹创建成功"); File folder1 = new File("F:\\World"); folder.renameTo(folder1); //重命名 System.out.println("重命名成功"); folder.delete(); File file = new File("F:\\World\\d.txt"); //查找文件 if(file.exists()){ System.out.println(file.isFile()); System.out.println(file.isDirectory ()); }else{ System.out.println("文件不存在,马上进行创建!"); } try { file.createNewFile(); //创建文件 } catch (IOException e) { e.printStackTrace(); }}}
Java中的IO操作
一:字节流
OutputStream和InputStream(基类)
FileOutputStream和FileInputStream(字节带缓冲输入、输出流)
BufferedInputStream和BufferedOutputStream(字节缓冲输入、输出流)
二:字符流
Reader和Writer(基类)
FileReader和FileWriter(定义字符输入、输出流)
BufferedReader和BufferedWriter(字符带缓冲输入、输出流)
LineNumberReader
IO操作:使用字节流读写数据
package test;import java.io.*;public class zlk { public static void main(String[] args) { try { //创建两个文件夹 File file1 = new File("F:\\test\\input.txt" ); file1.createNewFile(); File file2 = new File("F:\\test\\output.txt" ); file2.createNewFile(); //输出流:向文件中写数据 FileOutputStream fos=new FileOutputStream("F:\\test\\input.txt"); String outString="HelloWorld"; byte output[]=outString.getBytes("UTF-8"); fos.write(output); //输入流:从文件中读取数据 FileInputStream fis = new FileInputStream("F:\\test\\input.txt"); byte input[]=new byte[20]; fis.read(input); String s=new String(input,"UTF-8"); System.out.println(s); //输出流:向另一文件中复制数据 FileOutputStream fos1=new FileOutputStream("F:\\test\\output.txt"); fos1.write(s.getBytes()); fis.close(); fos.close(); fos1.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); }}}
带有缓冲的字符流读写数据:
package test;import java.io.*;public class zlk { public static void main(String[] args) { BufferedReader br=new BufferedReader(new InputStreamReader(System.in));//BufferedReader对象创建后获取控制台输入流File file=new File("F:\\test\\output.txt"); try { FileWriter fw=new FileWriter(file);BufferedWriter bw=new BufferedWriter(fw); //加了一个缓冲,缓冲写满后再将数据写入硬盘 ,极大的提高了性能 char[] cs=new char[50]; br.read(cs); //以使用read()方法从控制台读取一个字符 String s=new String(cs); System.out.println(s.trim()); bw.write(s); //将字符串写入磁盘文件中 br.close(); bw.close(); } catch (IOException e) { e.printStackTrace(); } }}
Java多线程编程
一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守候线程都结束运行后才能结束。
Java提供了两种创建线程方法:
• 通过继承Thread类本身: class NewThread extends Thread{}
new NewThread().start();
• 通过实现Runable接口: class NewThread implements Runnable{}
new Thread( new NewThread()).start();
继承Thread类和实现Runnable接口实现多线程,一个是多个线程分别完成自己的任务,一个是多个线程共同完成一个任务。如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。
实现Runnable接口比继承Thread类所具有的优势:
1):适合多个相同的程序代码的线程去处理同一个资源
2):可以避免java中的单继承的限制(继承了Thread类就不能再继承其他类了)
3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立。
通过继承Thread类本身创建线程:
package test;class NewThread extends Thread { //创建Thread的子类以控制线程的运行 public NewThread(String name){ super(name); //调用父类构造方法给thread命名 } public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Thread " +getName()+":"+ i); Thread.sleep(50); // 暂停线程,休眠 } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); }}public class zlk{ public static void main(String args[]) { NewThread t1=new NewThread("A"); NewThread t2=new NewThread("B"); NewThread t3=new NewThread("C"); t1.start(); t2.start(); t3.start(); System.out.println(t1.isAlive());//判断线程是否启动 }}
通过实现Runnable接口创建线程:
package test;class NewThread implements Runnable { String name; public NewThread(String name){ this.name=name; } public void run() { try { for(int i = 5; i > 0; i--) { System.out.println("Thread " +name+":"+ i); Thread.sleep(50); // 暂停线程 } } catch (InterruptedException e) { System.out.println("Child interrupted."); } System.out.println("Exiting child thread."); }}public class zlk{ public static void main(String args[]) { NewThread t1=new NewThread("A"); Thread demo=new Thread(t1); demo.start(); for(int i=0;i<50;++i){ if(i>10){ try{ demo.join(); //强制执行demo }catch (Exception e) { e.printStackTrace(); } } System.out.println("main 线程执行-->"+i); } } }
线程同步:
多线程环境中,可能存在多个线程同时使用某一资源造成资源冲突的情况(继承Thread类时)。多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问。
例1:
package test;class MyThread extends Thread { //创建Thread的子类以控制线程的运行 public MyThread(String name){ super(name); } public void run() { while(true) { sale(); }} private static int tickets=5; public static synchronized void sale() { //这里就是对函数进行同步。 if(tickets>0) { try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+" 剩余票数:"+ tickets); } tickets--; } }public class zlk { public static void main(String[] args) { MyThread t1 = new MyThread("窗口A"); MyThread t2 = new MyThread("窗口B"); MyThread t3 = new MyThread("窗口C"); t1.start(); t2.start(); t3.start(); } }
例2:
package test;public class zlk implements Runnable{ private int tickets = 10; public void run() { int count = 0; while(true) { synchronized(this) { if(tickets>-1) { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } count = 10 - tickets; System.out.println("当前有:"+tickets+" 张票" +" ,售出:"+count+"张票" +" ,售票员为:"+Thread.currentThread().getName()); tickets--; }else { break; } } } }public static void main(String[] args) {zlk r = new zlk();//调用Thread(Runnable threadOb,String threadName)构造方法.threadOb是一个实现Runnable 接口的类的实例,并且 threadName指定新线程的名字 Thread t1 = new Thread(r,"张三"); Thread t2 = new Thread(r,"李四"); Thread t3 = new Thread(r,"王五"); Thread t4 = new Thread(r,"赵六"); t1.start(); t2.start(); t3.start(); t4.start(); }}
Java中的Socket通信
Java socket通信已经被封装好了主要使用两个类ServerSocket 和Socket
首先写一个1v1的通信
Server:
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.ServerSocket;import java.net.Socket; public class GreetingServer{ // 设置端口号 public static int portNo = 3333; public static void main(String[] args) throws IOException { ServerSocket s = new ServerSocket(portNo); System.out.println("The Server is start: " + s); // 阻塞,直到有客户端连接 Socket socket = s.accept(); try { System.out.println("Accept the Client: " + socket); //设置IO句柄 BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream())); PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); while (true) { String str = in.readLine(); if (str.equals("byebye")) { break; } System.out.println("客户端发送的消息是: " + str); out.println("服务器收到:"+str); } } finally { System.out.println("close the Server socket and the io."); socket.close(); s.close(); } }}
Client:
import java.io.BufferedReader;import java.io.BufferedWriter;import java.io.IOException;import java.io.InputStreamReader;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.net.InetAddress;import java.net.Socket; public class GreetingClient { static String clientName = "Mike"; //端口号public static int portNo = 3333; public static void main(String[] args) throws IOException{ // 设置连接地址类,连接本地 InetAddress addr = InetAddress.getByName("localhost"); //要对应服务器端的3333端口号 Socket socket = new Socket(addr, portNo); try{ System.out.println("socket = " + socket); // 设置IO句柄BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));PrintWriter out = new PrintWriter(new BufferedWriter(New OutputStreamWriter(socket.getOutputStream())), true); out.println("Hello Server,I am " + clientName); String str = in.readLine(); System.out.println(str); out.println("byebye"); }finally { System.out.println("close the Client socket and the io."); socket.close(); } }}
通过程序里引入多线程的机制,可让一个服务器端同时监听并接收多个客户端的请求,并同步地为它们提供通讯服务。
基于多线程的通讯方式,将大大地提高服务器端的利用效率,并能使服务器端能具备完善的服务功能。
Server:
package tcp;import java.io.*;import java.net.*;//第二步,由于我们在服务器端引入线程机制,所以我们要编写线程代码的主体执行类ServerThreadCode,这个类的代码如下所示:class ServerThreadCode extends Thread { //客户端的socket private Socket clientSocket; //IO句柄 private BufferedReader sin; private PrintWriter sout; //默认的构造函数 public ServerThreadCode() {} public ServerThreadCode(Socket s) throws IOException { clientSocket = s; //初始化sin和sout的句柄 sin = new BufferedReader(new InputStreamReader(clientSocket .getInputStream())); sout = new PrintWriter(new BufferedWriter(new OutputStreamWriter( clientSocket.getOutputStream())), true); //开启线程 start(); } //线程执行的主体函数 public void run() { try { //用循环来监听通讯内容 for(;;) { String str = sin.readLine(); //如果接收到的是byebye,退出本次通讯 if (str.equals("byebye")) { break; } System.out.println("In Server reveived the info: " + str); sout.println(str); } System.out.println("closing the server socket!"); } catch (IOException e) { e.printStackTrace(); } finally { System.out.println("close the Server socket and the io."); try { clientSocket.close(); } catch (IOException e) { e.printStackTrace(); } } }}public class ThreadServer { //端口号 static final int portNo = 3333; public static void main(String[] args) throws IOException { //服务器端的socket ServerSocket s = new ServerSocket(portNo); System.out.println("The Server is start: " + s); try { for(;;) { //阻塞,直到有客户端连接 Socket socket = s.accept(); //通过构造函数,启动线程 new ServerThreadCode(socket); } } finally { s.close(); } }}
Client:
package tcp;import java.net.*;import java.io.*;//第二步,编写线程执行主体的ClientThreadCode类,同样,这个类通过继承Thread来实现线程的功能。class ClientThreadCode extends Thread { //客户端的socket private Socket socket; //线程统计数,用来给线程编号 private static int cnt = 0; private int clientId = cnt++; private BufferedReader in; private PrintWriter out; //构造函数 public ClientThreadCode(InetAddress addr) { try { socket = new Socket(addr, 3333); } catch(IOException e) { e.printStackTrace(); } //实例化IO对象try { in = new BufferedReader( new InputStreamReader(socket.getInputStream())); out = new PrintWriter( new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); //开启线程 start(); } catch(IOException e) { //出现异常,关闭socket try { socket.close(); } catch(IOException e2) { e2.printStackTrace(); } } } //线程主体方法public void run() { try { out.println("Hello Server,My id is " + clientId ); String str = in.readLine(); System.out.println(str); out.println("byebye"); } catch(IOException e) { e.printStackTrace(); } finally { try { socket.close(); } catch(IOException e) { e.printStackTrace(); } } }}//第三步,编写客户端的主体代码,在这段代码里,将通过for循环,根据指定的待创建的线程数量,通过ClientThreadCode的构造函数,创建若干个客户端线程,同步地和服务器端通讯。public class ThreadClient { public static void main(String[] args) throws IOException, InterruptedException { int threadNo = 0; InetAddress addr = InetAddress.getByName("localhost"); for(threadNo = 0;threadNo<3;threadNo++) { new ClientThreadCode(addr); } }}
- JAVA入门学习实例
- Drools学习 入门实例
- C++入门学习实例
- React学习入门实例
- ReactJS 入门实例学习
- React 入门实例学习
- Websocket 入门学习实例
- JAVA:lucene 入门学习,简单实例模访google搜索
- 正则表达式的学习入门实例(java篇)
- mina学习基础-入门实例-传输java对象(二)
- JAVA菜鸟入门篇 - File类实例学习 (30)
- Java Mail入门实例
- Java注解入门实例
- java入门实例HelloWorld
- java入门实例HelloWorld
- Java AIO 入门实例
- JAVA NIO入门实例
- Java WebService入门实例
- http与https的区别
- HDU-2059 龟兔赛跑(DP)
- 云存储中元数据方案与一致性哈希深入比较
- 顺序栈
- 2012年PPS笔试C++试题
- JAVA入门学习实例
- 欢迎使用CSDN-markdown编辑器
- android developers 打不开办法
- 敏捷测试的方法和实践
- Win7 64位操作系统下CreateProcess函数运行System32文件夹下批处理文件出错的原因
- ureCRT for Linux突破30天使用限制
- C++ 设计模式 - 6大设计原则之单一职责原则
- ant通配符
- 秒杀多线程第十二篇 多线程同步内功心法——PV操作上