多线程
线程
线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。
简单理解:应用软件中互相独立,可以同时运行的功能
并发:在同一时刻,有多个指令在单个CPU上交替执行
并行:在同一时刻,有多个指令在多个CPU_上同时执行
①继承Thread类的方式进行实现
②实现Runnable接口的方式进行实现
③利用Callable接口和Future接口方式实现
特点:可以获取多线程运行的结果
/*1.创建一个类MyCallable实现Callable接口
2.重写call (是有返回值的,表示多线程运行的结果)
3.创建MyCallable的对象(表示多线程要执行的任务)
4.创建FutureTask的对象 (作用管理多线程运行的结果)
5.创建Thread类的对象,并启动(表示线程)*/
//创建MyCallable的对象(表示多线程要执行的任务)
MyCallable mc = new MyCallable();
//创建FutureTask的对象(作用管理多线程运行的结果)
FutureTask<Integer> ft = new FutureTask<>(mc);
//创建线程的对象
Thread t1 = new Thread(ft);
//启动线程
t1.start();
//获取多线程运行的结果
Integer result = ft.get();
System. out. println(result);
方法对比
常见成员方法
设置线程的优先级
/*
setPriority(int newPriority) 设置线程的优先级
final int getPriority() 获取线程的优先级
*/
//创建线程要执行的参数对象
MyRunnable mr = new MyRunnable();
//创建线程对象
Thread t1 = new Thread(mr, "飞机");
Thread t2 = new Thread(mr, "坦克");
t1.setPriority(1);
t2.setPriority(10);
t1.start();|
t2.start();
守护线程
细节:
当其他的非守护线程执行完毕之后,守护线程会陆续结束
线程的生命周期
同步代码块
特点1:
锁默认打开,有一一个线程进去了,锁自动关闭
特点2:
里面的代码全部执行完毕,线程出来,锁自动打开
格式
synchronized (锁){
操作共享数据的代码
}
锁对象是唯一的
//表示这个类所有对象,都共享ticket
static int ticket = 0;
//锁对象,一定是唯一的
static Object obj = new Object();
@Override
public void run() {
while (true) {
//同步代码块
synchronized (obj) {//或者用mythteat.class
if (ticket < 100) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
ticket++;
System.out.println(getName() + "正在卖第" + ticket + "张票! ! ! ");
} else {
break;
}
}
}
}
同步方法
就是把synchronized关键字加到方法上
特点1:同步方法是锁住方法里面所有的代码
特点2:锁对象不能自己指定
非静态:this
静态:当前类的字节码文件对象
ctrl+alt+m抽取方法
@Override
public void run() {
//1.循环
while (true) {
//2.同步代码块(同步方法)
if (method()) break;
}
}
//this
private synchronized boolean method() {
//3.判断共享数据是否到了末尾,如果到了末尾
if (ticket == 100) {
return true;
} else {
//4.判断共享数据是否到了末尾,如果没有到末尾
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
ticket++;
System.out.println(Thread.currentThread().getName() + "在卖第" + ticket + "张票! ! ! ");
}
return false;
}
}
锁
lock锁
Lock中提供了获得锁和释放锁的方法
void lock():获得锁
void unlock():释放锁
Lock是接口不能直接实例化,这里采用它的实现类ReentrantLock来实例化
ReentrantLock的构造方法
ReentrantLock():创建一个ReentrantLock的实例
Lock Lock = new ReentrantLock();
等待唤醒机制
线程池
①创建一个池子,池子中是空的
②提交任务时,池子会创建新的线程对象,任务执行完毕,线程归还给池子
下回再次提交任务时,不需要创建新的线程,直接复用已有的线程即可
③但是如果提交任务时,池子中没有空闲线程,也无法创建新的线程,任务就会排队等待
ThreadPoolExecutor poll = new ThreadPoolExecutor(
3, //核心线程数量, 能小于0
6, //最 大线程数,不能小于0,最大数量>=核心线程数量
60, //空闲线程最大存活时间
TimeUnit.SECONDS,//时间单位
new ArrayBlockingQueue<>(3),//任务队列
Executors.defaultThreadFactory(),//创建线程工厂
new ThreadPoolExecutor.AbortPolicy()//住务的拒绝策略
);
网络编程
通信的软件架构CS\BS的各有什么区别和优缺点
CS:客户端服务端模式需要开发客户端
BS:浏览器服务端模式不需要开发客户端。
CS:适合定制专业化的办公类软件如: IDEA、网游
BS:适合移动互联网应用,可以在任何地方随时访问的系统。
网络编程三要素
IP
●设备在网络中的地址,是唯一的标识。
特殊IP
127.0.0.1(永远表示本机)
常见的CMD命令
ipconfig:查看本机IP地址
ping:检查网络是否连通
端口号
●应用程序在设备中唯一的标识。
注意:一个端0号只能被一个应用程序使用。
协议
●数据在网络中传输的规则,常见的协议有UDP、TCP、 http、 https、 ftp。
UDP协议
●用户数据报协议(User Datagram Protocol)
●UDP是面向无连接通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
发送数据
//1.创建DatagramSocket对象(快递公司)
//细节:
//绑定端口,以后我们就是通过这个端口往外发送
//空参:所有可用的端口中随机一个进行使用
//有参:指定端口号进行绑定
DatagramSocket ds = new DatagramSocket();
//2.打包数据
String str = "你好哇";
byte[] bytes = str.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bytes, bytes .length, address, port);
//3.发送数据
ds.send(dp);
//4.释放资源
ds.close();
接受数据
//1.创建DatagramSocket对象
//细节:
//在接收的时候,一定要绑定端口
//而且绑定的端口一定要跟发送的端口保持一致
DatagramSocket ds = new DatagramSocket(10086);
//2.接收数据包
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
//3.解析数据包
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress address = dp.getAddress();
int port = dp.getPort();
System.out.println("接收到数据" + new String(data, 0, len));
System.out.println("该数据是从" + address + "这台电脑中的" + port + "这个端口发出的");
//4.释放资源
ds.close();
先运行接收端
三种通信方式
①单播
以前的代码就是单播
②组播
组播地址: 224.0.0.0 ~ 239.255.255.255
其中224.0.0.0 ~ 224.0.0.255为预留的组播地址
③广播
广播地址: 255.255.255.255 .
TCP协议
●传输控制协议TCP(Transmission Control Protocol)
●TCP协议 是面向连接的通信协议。
速度慢,没有大小限制,数据安全。
客户端 发送数据
//1.创建Socket对象
//细节:在创建对象的同时会连接服务端
//如果连接不上,代码会报错
Socket socket = new Socket("127.0.0.1", 10000);
//2.可以从连接通道中获取输出流
OutputStream os = socket.getOutputStream();
//写出数据
os.write("aaa".getBytes());
//3.释放资源I
os.close();
socket.close();
//TCP协议,接收数据
//1.创建对象ServerSocker
ServerSocket ss = new ServerSocket(10000);
//2.监听客户端的链接
Socket socket = ss.accept();
//3.从连接通道中获取输入流读取数据
InputStream is = socket.getInputStream();
int b;
while ((b = is.read()) != -1) {
System.out.println((char) b);
}
//4.释放资源
socket.close();
ss.close();
三次握手
确认链接建立
四次挥手
确保链接断开,且数据处理完毕
反射
反射允许对成员变量,成员方法和构造方法的信息进行编程访问
获取class对象的三种方式
①Class. forName("全类名");
②类名. class
③对象. getClass();
获取全类名
//1.第一种方式
//全类名:包名+英名
//最为常用的
Class clazz1 = Class.forName("Student");
//2.第二种方式
//一般更多的是当做参数进行传递
Class clazz2 = Student.class;
//3.第三种方式
//当我们已经有了这个类的对象时,才可以使用。
Student s = new Student();
Class clazz3 = s.getClass();
System.out.println(clazz1 == clazz2);
System.out.println(clazz2 == clazz3);
构造方法
Class类中用于获取构造方法的方法
Constructor<?>[] getConstructors(): 返回所有公共构造方法对象的数组
Constructor<?>[] getDeclaredConstructors(): 返回所有构造方法对象的数组
Constructor<T> getConstructor(Class<?>... parameterTypes):返回单个公共构造方法对象
Constructor<T> getDeclaredConstructor(Class<>... parameterTypes):返回单个构造方法对象
Constructor类中用于创建对象的方法
T newInstance(Object... initargs): 根据指定的构造方法创建对象
setAccssible(boolean flag):设置为true,表示取消访问检查
利用反射获取成员变量
Class类中用于获取成员变量的方法
Field[] getFields():返回所有公共成员变量对象的数组
Field[] getDeclaredFields():返回所有成员变量对象的数组
Field getField(String name):返回单个公共成员变量对象
Field getDeclaredField(String name):返回单个成员变量对象
Field类中用于创建对象的方法
void set(Object obj, Object value):赋值
Object get(Object obj)获取值。
Class类中用于获取成员方法的方法
Method[] getMethods():返回所有公共成员方法对象的数组,(包含父类的)
Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象
Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象
Method类中用于创建对象的方法
Object invoke(Object obj, Object... args):运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写)
返回值:方法的返回值(如果没有就不写)
反射的作用
①获取任意一个类中的所有信息
②结合配置文件动态创建对象
动态代理
1.为什么需要代理?
代理可以无侵入式的给对象增强其他的功能
2.代理长什么样?
代理里面就是对象要被代理的方法
3. Java通过什么来保证代理的样子?
通过接口保证,后面的对象和代理需要实现同一个接口
接口中就是被代理的所有方法