多线程编程和Java网络编程
1. 线程概述
多任务处理有两种类型:基于进程、基于线程(进程是指一种“自包容”的运行程序,有自己的地址空间; 线程是进程内部单一的一个顺序控制流)
基于进程的特点是允许计算机同时运行两个或更多的程序、基于线程的多任务处理环境中,线程是最小的处理单位
2. 创建和启动线程
a. 编写一个继承Thread 类的类,然后重写Thread类的run()方法
public class thread extends Thread {
public void run() {
}
public static void main(String[] args) {
thread d = new thread();
d.start();
}
}
b. 编写一个类实现Runnable接口,然后将该类的实例与Thread对象联系在一起
public class threadrun implements Runnable { public void run(){
}
public static void main(String[] args) {
threadrun td = new threadrun();
Thread t = new Thread(td);
t.start();
}
}
3. 线程的优先级
A. Java 中的线程优先级是在 Thread 类中定义的常量:
NORM_PRIORITY : 值为 5
MAX_PRIORITY : 值为 10
MIN_PRIORITY : 值为 1
B . 有关优先级的方法有两个:
a. final void setPriority(int newp) : 修改线程的当前优先级
b. final int getPriority() : 返回线程的优先级
4. 使线程暂停执行的条件
A. 使用 sleep( ) 方法使线程睡眠
B. 通过调用 wait( ) 方法,使线程等待
C. 通过调用 yield( ) 方法,线程已显式出让CPU控制权
D. 线程由于等待一个I/O事件被阻塞
5. 线程同步:使用同步关键字synchronized
A.解决线程同步的方法:
a. 同步块
语法:synchronized (取得锁的对象){
//要锁定的代码
}
b.同步方法:在方法名关键字修饰前面使用synchronized
6. 死锁: 当两个线程循环依赖于一对同步对象时将发生死锁
7. 线程之间的相互通讯
方法:
a . 网络编程的实质就是编写程序直接或间接地通过网络协议与其它计算机上的某个程序进行通讯
b. 如何找到网络上的主机上的要进行通讯的程序 ?
c. 提供了IP地址和端口号,就可以找到网络上指定主机上要进行通讯的指定程序
a. 数据传输由TCP/IP分层模型中的传输层负责,该层包含TCP和UDP两种协议
b. TCP协议:较可靠的双向流协议、发送任意数量的数据、提供消息确认、错误检测和错误恢复等服务
c. UDP协议:比较不可靠
10 . 客户端和服务器
A. 服务器和客户端共同承担计算
a. 客户:向另一台计算机请求服务的计算机
b. 服务器:处理客户端请求的计算机
JDK预定义的网络编程相关类均存放在java.net包中。
常用的类:InetAddress 、Socket、ServerSocket 和 SocketImpl、DatagramPacket 和 DatagramSocket、 URL、URLConnection 和 URLEncoder
该类没有构造方法,所以不能直接利用new 关键字创建对象。我们可以使用以下常用方法来获取该类对象:
getLocalHost():返回表示本地主机InetAddress对象
getByName(String hostName):据主机名返回对象
getAddress() :返回IP地址
getHostName():取得IP地址代表的主机名
两个java程序通过一个双向的网络通信连接实现数据交换,这个双向链路的一端称之为Socket( Socket通常用来实现客户服务器之间的连接)
java.net包中的两个类Socket、ServerSocket分别用来实现客户端和服务端
A. 服务端( ServerSocket )编写步骤:
1).利用ServerSocket建立对服务端某个端口的监听
2).利用accept方法创建服务端Socket
3).利用已建立的socket创建输入输出流
4).关闭输入输出流,关闭socket,关闭server
B. 客服端( Socket )编写步骤:
1).创建客户端Socket向服务器发起连接请求
2).利用已建立的socket创建输入输出流
3).关闭输入输出流,关闭socket,关闭server
A. 用户报文协议(UDP)是用于将二进制数据从一台计算机发送到另一台计算的非连接协议
B. 数据报包的发送者和接收者都使用java.net.DatagramSocket类分别发送和接收包
D. 接收数据报包需要执行如下步骤:
1). 创建一个足够大的字节数组,用于存储要接收的包的数据
2). 使用该字节数组实例化一个DatagramPacket对象
3). DatagramSocket被实例化,它被指定该套接字要绑定到的本地主机上的一个端口
4). 调用DatagramSocket类的receive()方法,将DatagramPacket对象传入该方法。这将导致执行线程阻塞,直到接收到一个数据报包或者发生了超时
E. 发送数据报包需要执行如下步骤:
1). 创建一个足够大的字节数组,用于存储要发送的包数据,用该数据填充数组
2). 创建一个新的DatagramPacket 对象,用于存储上面的字节数组,以及服务器名和接收者的端口号
3). DatagramSocket被实例化,它被指定套接字要绑定到本地主机的哪个端口
4). DatagramSocket类的send()方法被调用,传入DatagramPacket对象
例题:简易局域网聊天系统–局域网QQ:
服务器端
实现简易的启动停止服务器端操作,能记录基本日志:客户连接、消息传送,能查看连接客户的昵称。
启动服务器后开始监听客户端连接,创建一个新线程实现该监听操作。
// 启动新线程监听客户端
new Thread(new Runnable() {
public void run() {
writeLog("开始监听客户端:");
listen();
}
}).start();
为每一个客户端连接开启一个新线程处理通讯,包括处理输入流与输出流。
// 每监听到一个客户端连接,启动一个新线程处理该连接
new Participant(this, socket, usersList).start();
获取用户不同的行为实现不同的操作 String flag = in.readUTF();
// 获取用户操作行为
if ("validateUser".equals(flag)) { // 验证用户是否存在
// ……………………
} else if ("newUser".equals(flag)) { // 新用户登录
// ……………………
} else if ("message".equals(flag)) { // 用户间发送消息
// ……………………
} else if ("userList".equals(flag)) { // 获取用户列表
// ……………………
}
在服务器端,采用Map保存每个客户端对应的套接字:
private Map<String, Socket> usersList = new HashMap<String, Socket>();
key为客户端连接时输入的用户昵称,value为对应的套接字对象。
各客户端用户间发送消息时,通过服务器转发送该信息:
String sender = in.readUTF(); // 发送者
String receiver = in.readUTF(); // 接收者
String message = in.readUTF(); // 消息
// 添加日志
server.writeLog(sender + " 向 " + receiver + "发送消息:" + message);
// 服务器向目标转发消息,先获得要转发后的目标套接字对象
Socket socket = server.getUsersList().get(receiver);
System.out.println(out);
if (socket == null) { // 服务器已删除该客户端连接信息
out.writeUTF("message");
out.writeUTF("系统服务器");
out.writeUTF(receiver + "已退出系统,无法再发送消息");
out.flush();
} else {
DataOutputStream thatOut = new DataOutputStream(socket.getOutputStream()); // 创建输出流对象
if (thatOut != null) {
thatOut.writeUTF("message");
thatOut.writeUTF(sender);
thatOut.writeUTF(message);
thatOut.flush(); // 写入客户端输出流中
}
}
客户端
先通过登录窗体实现服务器端连接,然后输入登录用户昵称,如果服务器端还未保存该昵称,则登录成功。登录成功后,可以直接先读取到服务器端已有登录用户的昵称,显示到列表中。双击好友列表中的任一项打开聊天对话框,然后双方可以开始聊天。
创建到服务器的套接字对象:
// 创建套接字对象
socket = new Socket(serverIp.getText().trim(), Integer.parseInt(port.getText().trim()));
连接的服务器与端口从窗体文本框中获取到。
登录成功后,将昵称发送到服务器保存:
out.writeUTF("newUser");
out.writeUTF(nickname); out.flush();
刷新好友列表:
// 读取流中信息
String flag = in.readUTF();
if ("userList".equals(flag)) { // 好友列表
String[] userList = in.readUTF().split("::::"); // 获取好友列表,使用标记分隔
// 创建好友列表模型
DefaultListModel list = new DefaultListModel();
for (int i = 0; i < userList.length; i++) {
list.addElement(userList[i]);
}
friends.setModel(list); // 设置模型
friends.validate(); // 重绘
}
发送消息给某个好友:
out.writeUTF("message");
out.writeUTF(sender);
out.writeUTF(recipient);
out.writeUTF(textArea.getText());
out.flush();
开启新线程读取服务器转发的好友信息:
String flag = in.readUTF();
if ("message".equals(flag)) {
String sender = in.readUTF();
String msg = in.readUTF();
String message = sender + " 对你说:" + msg + "\n";
jTextArea.append(message);
}
多线程编程和Java网络编程的更多相关文章
- Java-Runoob-高级编程:Java 网络编程
ylbtech-Java-Runoob-高级编程:Java 网络编程 1.返回顶部 1. Java 网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.n ...
- Java网络编程和NIO详解开篇:Java网络编程基础
Java网络编程和NIO详解开篇:Java网络编程基础 计算机网络编程基础 转自:https://mp.weixin.qq.com/s/XXMz5uAFSsPdg38bth2jAA 我们是幸运的,因为 ...
- Java工程师学习指南第5部分:Java网络编程与NIO
本文整理了微信公众号[Java技术江湖]发表和转载过的Java网络编程相关优质文章,想看到更多Java技术文章,就赶紧关注本公众号吧. 深度解读 Tomcat 中的 NIO 模型 [Java基本功]浅 ...
- day05 Java网络编程socket 与多线程
java网络编程 java.net.Socket Socket(套接字)封装了TCP协议的通讯细节,是的我们使用它可以与服务端建立网络链接,并通过 它获取两个流(一个输入一个输出),然后使用这两个流的 ...
- java 网络编程复习(转)
好久没有看过Java网络编程了,现在刚好公司有机会接触,顺便的拾起以前的东西 参照原博客:http://www.cnblogs.com/linzheng/archive/2011/01/23/1942 ...
- java网络编程serversocket
转载:http://www.blogjava.net/landon/archive/2013/07/24/401911.html Java网络编程精解笔记3:ServerSocket详解ServerS ...
- Java 网络编程(转)
一,网络编程中两个主要的问题 一个是如何准确的定位网络上一台或多台主机,另一个就是找到主机后如何可靠高效的进行数据传输. 在TCP/IP协议中IP层主要负责网络主机的定位,数据传输的路由,由IP地址可 ...
- 【Java基础】Java网络编程基础知识
什么是网络编程 网络编程是通过使用套接字来达到进程间通信目的,那什么是套接字呢?其实套接字是支持TCP/IP的网络通信的基本操作单元,可以看做是不同主机之间的进程进行双向通信的端点,简单的说就是通信的 ...
- 【Java】Java网络编程菜鸟进阶:TCP和套接字入门
Java网络编程菜鸟进阶:TCP和套接字入门 JDK 提供了对 TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Datagram Protoco ...
随机推荐
- 剔除重复jar包,查找重复类
作为程序员,没有遇到过jar包冲突,不是你幸运,就是你还年轻. jar包冲突有着无穷的魔力,一提到就会有说不完的怨愤,道不清的忧伤,这都是内伤.jar 包冲突就像深藏地底的地雷,看上去平常无奇,一切是 ...
- Java_Web三大框架之Hibernate+jsp+selvect+HQL登入验证
刚开始接触Hibernate有些举手无措,觉得配置信息太多.经过一个星期的适应,Hibernate比sql简单方便多了.下面做一下Hibernate+jsp+selvect+HQL登入验证. 第一步: ...
- js 时间 Fri Dec 12 2014 08:00:00 GMT+0800
第一种var d = new Date('Fri Dec 12 2014 08:00:00 GMT+0800'); ) + '-' + d.getDate() + ' ' + d.getHours() ...
- Redis 之sentinel运维监控
有三台redis服务器6379.6380.6381,配置6379为主服务器,6380与6381都为6379的从服务器.如果主服务器6379挂掉了,我们怎么办? 方式一:手动修改从服务器的配置,将638 ...
- CAD动态绘制带面积周长的圆(com接口)
CAD绘制图像的过程中,画圆的情况是非常常见的,用户可以在控件视区点取任意一点做为圆心,再动态点取半径绘制圆. 主要用到函数说明: _DMxDrawX::DrawCircle 绘制一个圆.详细说明如下 ...
- CPU内部组成及原理
CPU,Central Processing Unit,翻译过来叫中央处理器.是一块超大规模的集成电路,是一台计算机的运算核心(Core)和控制核心( Control Unit).电脑中所有操作都由C ...
- 关于panda中dataframe的与&运算*(stackoverflow高票答案)
85 down vote favorite 31 What explains the difference in behavior of boolean and bitwise operations ...
- 浏览器 <html>相关
若页面需默认用极速核,增加标签:<meta name="renderer" content="webkit"> https://blog.csdn ...
- 二叉堆 及 大根堆的python实现
Python 二叉堆(binary heap) 二叉堆是一种特殊的堆,二叉堆是完全二叉树或者是近似完全二叉树.二叉堆满足堆特性:父节点的键值总是保持固定的序关系于任何一个子节点的键值,且每个节点的左子 ...
- JavaScript学习笔记之DOM对象
目录 1.Document 2.Element 3.Attribute 4.Event 1.Document 每个载入浏览器的 HTML 文档都会成为 Document 对象,Document 对象允 ...