为了解决在程序中不同客户端在同一服务端中都可以进行数据发送的情况,要使用多线程将其进行并联操作
一、多线程
线程可以并发执行多个代码片段,使得这些代码片段直接运行是互不干涉的;
创建线程有两种方式,
方式一:
- 继承Thread类并重写run方法
* - 注:run方法的内容就是该线程要执行的任务
第一种创建线程的方式的优点是定义简单,适合匿名内部类形式创建
缺点主要有两个:
- 1:java是单继承的,这导致继承了Thread就无法再继承其他类取复用方法了,这在
- 实际开发中很不方便
- 2:将任务定义在线程中,会导致线程和任务存在必然的耦合关系,不利于线程的复用
方式二:
- 实现Runnable接口单独定义线程任务。
调用线程要用start方法,而不是run方法
* 当线程的start方法调用后,该线程纳入到线程调度器中统一管理,该方法调用后线程的run方法会马上被调用(当该线程第一次分配到CPU时间片开始运行时)
二、创建多线程
2.1 方法一
package thread;
public class ThreadDemo1 {
public static void main(String[] args) {
Thread t1 = new MyThread1();
Thread t2 = new MyThread2();
t1.start();
t2.start();
}
}
class MyThread1 extends Thread{
public void run(){
for(int i=0;i<500;i++){
System.out.println("Who are you?");
}
}
}
class MyThread2 extends Thread{
public void run(){
for(int i =0 ;i<500;i++){
System.out.println("i am repair");
}
}
}
2.2 方法二
package thread;
/**
* 第二种创建线程的方法
* 实现Runnable接口单独定义线程任务。
* @author 毛
*
*/
public class ThreadDemo2 {
public static void main(String[] args) {
//创建任务
Runnable r1 = new MyRunnable1();
Runnable r2 = new MyRunnable2();
//创建线程
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
}
class MyRunnable1 implements Runnable{
public void run(){
for(int i = 0;i<500;i++){
System.out.println("hello");
}
}
}
class MyRunnable2 implements Runnable{
public void run(){
for(int i=0;i<500;i++){
System.out.println("wellcome!");
}
}
}
2.3 使用匿名内部类实现两种方法
package thread;
/**
* 使用匿名内部类形式创建线程
* @author 毛
*
*/
public class ThreadDemo3 {
public static void main(String[] args) {
Thread t1 =new Thread() {
public void run(){
for(int i=0;i<500;i++){
System.out.println("Who are you?");
}
}
};
//想使用lambda表达式来替换匿名内部类,则匿名内部类只能实现一个接口其接口中只有一个抽象方法
// Runnable r2 = new Runnable(){
// public void run(){
// for(int i=0;i<500;i++){
// System.out.println("wellcome!");
// }
// }
// };
Runnable r2 = () -> {
for(int i=0;i<500;i++){
System.out.println("i am iroman");
}
};
Thread t2 = new Thread(r2);
t1.start();
t2.start();
}
三、获取线程的相关信息
3.1 获取运行方法的线程
static Thread currentThread()
- 线程提供的该静态方法用于获取运行这个方法的线程
- java中所有代码都是靠线程运行的,运行main方法的线程称为"主线程"
public class CurrentThreadDemo {
public static void main(String[] args) {
Thread t = Thread.currentThread();//获取运行main方法的路线
System.out.println("运行main方法的线路是:"+t);
dosome();//main方法调用dosome方法
Thread t2 = new Thread(){
public void run(){
Thread t = Thread.currentThread();
System.out.println("自定义线程:"+t);
dosome();//定义线程t2调用dosome方法
}
};
t2.start();
}
public static void dosome(){
//获取运行dosome方法的线程
Thread t = Thread.currentThread();
System.out.println("运行dosome方法的线程:"+t);
}
}
3.2 获取线程的名字、ID
String name = t.getName();
System.out.println("线程名字:"+name);
long id = t.getId();
System.out.println("唯一标识:"+id);
3.3 查看当前线程状态
//查看当前线程是否还活着
boolean isAlive = t.isAlive();
System.out.println("isAlive:"+isAlive);
//查看线程是否为守护线程
boolean isDaemon = t.isDaemon();
System.out.println("isDaemon:"+isDaemon);
//查看线程是否中断
boolean isInterrupted = t.isInterrupted();
System.out.println("isInterrupted:"+isInterrupted);
3.4 查看当前线程的优先级并且调整
线程获取CPU时间片并发运行,一切听从线程调度,线程是不能主动索取时间片的,只能被动分配。
调整线程的优先级可以最大限度的干涉分配时间片的概率,原则上优先级越高的线程获取CPU时间片的次数越多。
int priority = t.getPriority();
System.out.println("优先级:"+priority);
Thread max = new Thread(){
public void run(){
for(int i=0;i<1000;i++);{
System.out.println("max");
}
}
};
Thread norm = new Thread(){
public void run(){
for(int i=0;i<1000;i++);{
System.out.println("nor");
}
}
};
Thread min = new Thread(){
public void run(){
for(int i=0;i<1000;i++);{
System.out.println("min");
}
}
};
//线程优先级1最低,5默认,10最高
max.setPriority(Thread.MAX_PRIORITY);
min.setPriority(Thread.MIN_PRIORITY);
min.start();//最慢结束输出
norm.start();
max.start();//最快结束输出
四、TCP通信的实现
4.1 聊天室的客户端
package socket;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
/**
* 聊天室的客户端
* @author 毛
*
*/
public class Client {
/*
* java.net.Socket 套接字
* Socket封装了TCP协议的通讯细节,使用它就可以与服务端建立网络连接了,
* 并且进行通讯。这里的通讯是以两条流的读写完成与服务端的数据交换的。
*/
private Socket socket;
/**
* 客户端构造方法,用于初始化客户端
*/
public Client() {
try {
/*
* 实例化Socket时需要传入两个参数:
* 1:服务端的地址信息(IP)
* 2:服务端打开的端口
*
* 我们可以通过IP找到网络上的服务端计算机,通过其打开的端口
* 可以连接到服务端应用程序。
*/
System.out.println("正在连接服务端...");
socket = new Socket("localhost",8088);
System.out.println("已连接服务端!");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 客户端开始工作的方法
*/
public void start() {
try {
/*
* Socket提供的方法:
* OutputStream getOutputStream()
* 通过socket的该方法获取的输出流写出的字节会通过网络发送给
* 远端计算机。
*/
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"UTF-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw,true);
Scanner scanner = new Scanner(System.in);
while(true) {
String message = scanner.nextLine();
pw.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
4.2 聊天室的服务端
package socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 聊天室的客服端
* @author 毛
*
*/
public class Server {
/*
* 服务端使用的是ServerSocket
* 它有两个作用:
* 1:向系统申请端口。
* 2:接收请求该端口的所有客户端的连接。
*/
private ServerSocket server;
/**
* 服务端构造方法,用来初始化服务端
*/
public Server() {
try {
/*
* 实例化的同时向系统申请服务端口,客户端Socket就是通过这个
* 端口与服务端建立连接的。如果该端口被系统其他程序占用了则
* 会抛出异常:
* java.net.BindException:address already in use: JVM_bind
*
* 遇到该错误时解决办法:
* 1:首先检查是否自己开启过两次服务端,因为第一次启动已经占用了
* 该端口,如果再启动一遍时还申请该端口就会提示被占用了。
* 2:如果没有启动过两次,那说明系统其他程序占用该端口了,需要更
* 换一个可用的。
*/
System.out.println("正在启动服务端...");
server = new ServerSocket(8088);
System.out.println("服务端启动完毕!");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 服务端开始工作的方法
*/
public void start() {
try {
/*
* ServerSocket提供的方法:
* Socket accept()
* 该方法是一个阻塞方法,调用该方法后程序"卡住",此时开始等待
* 客户端的连接,一旦客户端实例化Socket并连接服务端这边申请的
* 端口(8088)时,accept方法会立即返回一个Socket实例,此时等于
* 和客户端建立了连接。服务端通过返回的这个Socket就可以与客户端
* 进行交互了。
* 多次调用accept方法可以接收多个客户端的连接。
*/
while(true){
System.out.println("等待客户端连接...");
Socket socket = server.accept();
System.out.println("一个客户端连接了!");
//启动一个线程处理客户端交互
ClientHandler handler = new ClientHandler(socket);
Thread t = new Thread(handler);
t.start();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
/**
* 该线程任务用来与客户端交互
*/
private class ClientHandler implements Runnable{
private Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
public void run(){
try{
/*
* Socket提供的方法:
* InputStream getInputStream();
* 通过该方法获取的输入流读取的字节是远端计算机发送过来的字节
*/
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,"UTF-8");
BufferedReader br = new BufferedReader(isr);
String message = "";
while((message = br.readLine())!=null) {
System.out.println("客户端说:"+message);
}
}catch(Exception e){
}
}
}
}
练习
package txst;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import org.omg.CORBA.portable.InputStream;
public class Server {
/*5 private ServerSocket server;
public Server(){
try{
System.out.println("服务器启动ing");
server = new ServerSocket(8088);
System.out.println("服务器启动完成");
}catch(IOException e){
e.printStackTrace();
}
}
public void start(){
try {
while(true){
System.out.println("等待客户连接");
Socket socket = server.accept();
System.out.println("一客户连接");
ClientHandler handler = new ClientHandler(socket);
Thread t = new Thread(handler);
t.start();
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
private class ClientHandler implements Runnable{
private Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
public void run (){
try{
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,"utf-8");
BufferedReader br = new BufferedReader(isr);
String message = "";
while((message = br.readLine())!=null){
System.out.println("客户说:"+message);
}
}catch(Exception e){
e.printStackTrace();
}
}
}*/
/*4
private ServerSocket server;
public Server(){
try{
System.out.println("Server Starting");
server = new ServerSocket(8088);
System.out.println("Start end ");
}catch(IOException e){
e.printStackTrace();
}
}
public void start(){
try{
while(true){
System.out.println("white..");
Socket socket = server.accept();
System.out.println("a accepted");
ClientHandler handler = new ClientHandler(socket);
Thread t = new Thread(handler);
t.start();
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
private class ClientHandler implements Runnable{
private Socket socket;
public ClientHandler(Socket socket){
this.socket = socket;
}
public void run(){
try{
InputStream in = (InputStream) socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,"utf-8");
BufferedReader br = new BufferedReader(isr);
String message = "";
while((message = br.readLine())!=null){
System.out.println("say:"+message);
}
}catch(Exception e){
}
}
}
*/
/*3
private ServerSocket server;
public Server(){
try{
System.out.println("white..Start");
server = new ServerSocket(8088);
System.out.println("Started");
}catch(IOException e){
e.printStackTrace();
}
}
public void start(){
try{
while(true){
System.out.println("whit accept");
Socket socket = server.accept();
System.out.println("a accepted");
CliendHandler handler = new CliendHandler(socket);
Thread t = new Thread(handler);
t.start();
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
private class CliendHandler implements Runnable{
private Socket socket;
public CliendHandler (Socket socket){
this.socket = spcket;
}
public void run(){
try{
InputStream in = socket.getInputStream(socket);
InputStreamReader isr = new InputStreamReader(in,"utf-8");
BufferedReader br = new BufferedReader(isr);
String message = "";
while((message=br.readLine())!=null){
System.out.println("say:"+message);
}
}catch(Exception e){
}
}
}
*/
/*2
private ServerSocket server;
public Server(){
try{
System.out.println("starting");
server = new ServerSocket(8088);
System.out.println("started");
}catch(IOException e){
e.printStackTrace();
}
}
public void start(){
try{
while(true){
System.out.println("whit");
Socket socket = server.accept();
System.out.println("a accepted");
CliendHandler handler = new CliendHandler(socket);
Thread t = new Thread(handler);
t.start();
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
private class CliendHandler implements Runnable{
private Socket socket;
public CliendHandler(Socket socket){
this.socket = socket;
}
public void run(){
try {
InputStream in = socket.getInputStream(socket);
InputStreamReader isr = new InputStreamReader(in,"utf-8");
BufferedReader br = new BufferedREader(isr);
String message = "";
while((message = br.readLine())!=null){
System.out.println("say:"+message);
}
}catch(Exception e){
}
}
}
*/
/*1
private ServerSocket server;
public Server(){
try{
System.out.println("starting");
server = new ServerSocket(8088);
System.out.println("started");
}catch(IOException e){
e.printStackTrace();
}
}
public void start(){
try{
while(true){
System.out.println("whit");
Socket socket = server.accept();
System.out.println("a accepted");
CliendHandler handler = new CliendHandler(socket);
Thread t = new Thread(handler);
t.start();
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
private class CliendHandler implements Runnable{
private Socket socket;
public CliendHandler(Socket socket){
this.socket = socket;
}
public void run(){
try {
InputStream in = socket.getInputStream(socket);
InputStreamReader isr = new InputStreamReader(in,"utf-8");
BufferedReader br = new BufferedREader(isr);
String message = "";
while((message = br.readLine())!=null){
System.out.println("say:"+message);
}
}catch(Exception e){
}
}
}
*/
}
/*5private Socket socket;
public Client(){
try{
System.out.println("accept ing");
socket = new Socket("localhost",8088);
System.out.println("accepted");
}catch(Exception e){
e.printStackTrace();
}
}
public void start(){
try{
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"uft-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw,true);
Scanner scan = new Scanner(System.in);
while(true){
String message = scan.nextLine();
pw.println(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}*/
/*4
private Socket socket;
public Client(){
try{
System.out.println("accept ing");
socket = new Socket("localhost",8088);
System.out.println("accepted");
}catch(Exception e){
e.printStackTrace();
}
}
public void start(){
try{
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw);
Scanner scan = new Scanner(System.in);
while(true){
String message = scan.nextLine();
pw.println(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}*/
/*3 private Socket socket;
public Client(){
try{
System.out.println("accept ing");
socket = new Socket("localhost",8088);
System.out.println("accepted");
}catch(Exception e){
e.printStackTrace();
}
}
public void start(){
try{
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw);
Scanner scan = new Scanner(System.in);
while(true){
String message = scan.nextLine();
pw.println(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}*/
/*2private Socket socket;
public Client(){
try{
System.out.println("accept ing");
socket = new Socket("localhost",8088);
System.out.println("accepted");
}catch(Exception e){
e.printStackTrace();
}
}
public void start(){
try{
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw);
Scanner scan = new Scanner(System.in);
while(true){
String message = scan.nextLine();
pw.println(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}*/
/*1private Socket socket;
public Client(){
try{
System.out.println("accept ing");
socket = new Socket("localhost",8088);
System.out.println("accepted");
}catch(Exception e){
e.printStackTrace();
}
}
public void start(){
try{
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,"utf-8");
BufferedWriter bw = new BufferedWriter(osw);
PrintWriter pw = new PrintWriter(bw);
Scanner scan = new Scanner(System.in);
while(true){
String message = scan.nextLine();
pw.println(message);
}
}catch(Exception e){
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}*/