本帖最后由 小石姐姐 于 2018-4-26 14:32 编辑
多线程&网络编程&反射
多线程多线程的实现方式线程的生命周期线程的声明周期中有5种状态
创建: new一个线程对象, 此时还没有调用start() 就绪: 调用start()方法后, 进入就绪状态, 等待CPU执行 运行: 获取了CPU的执行权, 开始运行线程 阻塞: 调用了sleep(), wait(), 或由于IO操作导致阻塞. 阻塞解除后仍会返回就绪状态, 等待CPU执行 销毁: 线程执行完毕
+---------------------------+
| 阻塞 |
+--v----------------------^-+
| |
|解除阻塞 被阻塞|
new | |
+------+ +--v---+ +--^---+ +------+
| | start() | >--------------> | 线程执行结束 | |
| 创建 >------------> 就绪 | CPU调度 | 运行 >---------------> 销毁 |
| | | <--------------< | | |
+------+ +------+ +------+ +------+线程之间的通信使用Object类的成员方法
void wait(): 使当前线程处于等待状态, 并且会立刻释放锁 void notify(): 随机唤醒一个处于等待状态的线程 void notifyAll(): 唤醒所有处于等待状态的线程 注意: 这三个方法必须在同步代码块中, 且只能用锁对象来调用, 否则会抛异常
sleep()和wait()的区别
sleep
让当前线程在指定时间内睡眠, 时间结束后继续执行 是Thread类的静态方法 不会释放锁
wait
让当前线程等待, 直到有人唤醒 是Object类的非静态方法 等待会立刻释放锁
注意:
线程释放锁的3种情况
死锁: dead lock
发生死锁的原因:
同步代码块内的线程, 可能处在死循环, IO阻塞, sleep()状态, 导致内部持有锁的线程无法出同步代码块 多个线程互相持有锁又不释放锁: 两个线程执行的任务都是双层同步代码块, 每层同步都需要一个锁, 两个线程中同步代码块的锁是相反的
死锁的结果: 程序卡死, 无法继续执行 如何避免死锁:
网络网络通信三要素UDP和TCP的区别UDP: USER DATAGRAM PROTOCOL, 用户数据报协议.
TCP: TRANSMISSION CONTROL PROTOCOL, 传输控制协议
InetAddress概述和测试java.net.InetAddress类: 用于表示IP地址对象 (InetAddress的实例包含 IP 地址,还可能包含相应的主机名) 静态方法
static InetAddress getLocalHost(): 获取本机的InetAddress对象 static InetAddress getByName(String host): 根据主机名或IP的字符串获取主机的InetAddress对象 static InetAddress getLoopbackAddress(): 获取回环地址的InetAddress对象. 即127.0.0.1或localhost static InetAddress getByAddress(byte[] addr): 根据IP获取InetAddress对象
成员方法
UDP协议发送数据
// 1. 为发送端创建Socket对象(DatagramSocket)
DatagramSocket datagramSocket = new DatagramSocket();
// 2. 创建数据并打包
DatagramPacket datagramPacket = new DatagramPacket(byte数组, 数组长度, InetAddress对象, 端口号);
// 3. 发送数据
datagramSocket.send(datagramPacket);
// 4. 释放资源
datagramSocket.close();UDP协议接收数据
// 1. 创建接收端Socket对象:
DatagramSocket datagramSocket = DatagramSocket(接收方端口号);
// 2. 接收数据
DatagramPacket datagramPacket = new DatagramPacket(byte数组, 数组长度);
datagramSocket.receive(datagramPacket); // 该方法会阻塞等待接收数据
// 3. 解析数据
InetAddress inetAddress = datagramPacket.getAddress(); // 获取发送方IP地址
byte[] bytes = datagramPacket.getData(); // 获取数据
int dataLength = datagramPacket.getLength(); // 获取数据长度
String s = new String(bytes, 0, dataLength);
// 4. 输出数据
System.out.println(s);
// 5. 释放资源:
datagramSocket.close();TCP协议发送数据
// 1. 创建客户端Socket对象(建立连接)
Socket socket = new Socket(InetAddress地址, 端口号);
// 2. 获取输出流对象
OutputStream outputStream = socket.getOutputStream();
// 3. 发送数据
outputStream.write(byte数组);
// 4. 释放资源
socket.close();TCP协议接收数据
// 1. 创建服务端ServerSocket对象:
ServerSocket serverSocket = new ServerSocket(端口号); // 指定要监听的端口号
// 2. 监听数据
Socket socket = serverSocket.accept(); // 该方法会阻塞, 直到有客户端连接
// 3. 获取输入流对象
InputStream inputStream = socket.getInputStream();
// 4. 获取数据
int dataLength = inputStream.read(装数据的byte[]数组);
String s = new String(byte[], 0, dataLength);
// 5. 输出数据
System.out.println(s);
// 6. 释放资源:
socket.close();
serverSocket.close();反射获取字节码对象的3种方法反射使用的相关类和方法java.lang.Class类: 类的字节码对象
获取构造方法
Constructor<?>[] getConstructors(): 以数组形式返回该类中所有public的构造方法. 如果没有public的, 则数组长度为0 Constructor<?>[] getDeclaredConstructors(): 以数组形式返回该类中所有权限的构造方法, 包括private的. 如果该类是接口, 基本类型, 数组, void, 则数组长度为0 Constructor<T> getConstructor(Class<?>... parameterTypes): 根据参数列表返回指定的public的构造方法. 参数列表填写参数的字节码对象 Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes): 根据参数列表返回指定的所有权限的构造方法, 包括private的. 参数列表填写参数的字节码对象
获取成员属性
Field[] getFields(): 获取所有public的成员变量 Field[] getDeclaredFields(): 获取所有权限的成员变量, 包括private的 Field getField(String fieldName): 通过指定的成员变量名获取指定的public的成员变量 Field getDeclaredField(String fieldName): 通过指定的成员变量名获取指定的所有权限的成员变量, 包括private的
获取成员方法
Method[] getMethods(): 返回所有public的方法数组 Method[] getDeclaredMethods(): 返回所有权限的方法数组 Method getMethod(String name, Class<?>... parameterTypes): 获取public的方法, 传入方法名和方法形参字节码对象 Method getDeclaredMethod(String name, Class<?>... parameterTypes): 获取所有权限的指定方法, 传入方法名和方法形参字节码对象
创建对象
java.lang.reflect.Constructor类: 构造方法对象
T newInstance(): 通过无参构造方法对象创建一个类的对象 T newInstance(Object... initargs): 通过有参构造方法对象创建一个类的对象, 传入构造方法所需的参数列表 void setAccessible(boolean canAccess): 设置为true时禁用Java的访问安全检查, 可以访问所有权限的构造方法
java.lang.reflect.Field类: 成员变量对象
Object get(Object obj): 获取指定对象的属性值 void set(Object obj, Object value): 将指定对象的属性值设置为指定的值 void setAccessible(boolean canAccess): 设置为true时禁用Java的访问安全检查, 可以访问所有权限的成员属性
java.lang.reflect.Method类: 成员方法对象
Object invoke(Object obj, Object... args): 调用指定对象的成员方法 void setAccessible(boolean canAccess): 设置为true时禁用Java的访问安全检查, 可以访问所有权限的成员方法
JavaBeanBeanUtils工具类BeanUtils类常用的3个方法 static void setProperty(Object bean, String name, Object value): 给JavaBean对象的成员属性赋值, 传入对象, 成员属性名, 属性值 static String getProperty(Object bean, String name): 获取JavaBean成员属性的属性值, 传入对象, 成员属性名, 返回属性值的字符串形式 static void populate(Object bean, Map properties): 给JavaBean对象的成员属性赋值, 传入对象, Map的key是属性名, value是属性值
|