本帖最后由 小石姐姐 于 2018-4-25 17:00 编辑
多线程
进程 : 是一个应用程序在内存中的执行区域,比如一个正在运行的程序,可以有一个或者多个进程 一个正在运行的程序,可以有一个或多个进程,每个进程都会占用一部分的系统资源,如CPU,内存,磁盘,网络等 而线程则是一个进程中的一个执行路径 如: 一个进程中可以有一个或多个线程 每个线程可以执行自己的代码 多个线程各自执行的任务可以同时进行 线程的执行依靠CPU调度分配 单核CPU: 靠CPU不断高速的随机的切换执行的线程, 达到看似同时进行的效果 多核CPU: 每个CPU可能完全执行一个线程, 或者多个CPU各自不断高速随机切换, 更高效 单线程: 同一时间只做一件事情, 安全性高, 效率低. 多线程: 同一时间做多件事, 安全性低, 效率高. 什么是并发? 并发就是并行发生, 同时发生, 多线程就可以实现并发 同步: sync, 同步是指一步接一步的执行, 一个执行完毕再开始执行下一个. 异步: async,同时执行多步, 每个步骤何时结束不确定. 阻塞: 上一行代码正在执行, 还没有执行完毕, 程序就阻塞了, 下一行代码必须等上一行不再阻塞后才能执行 创建线程的第一种方式: 继承Thread类 Thread Thread(): 创建Thead对象 Thread Thread(Runnable r)`: 通过Runnable对象创建Thread对象 Thread Thread(Runnable r, String threadName): 通过Runnable对象创建Thread对象并指定线程名 成员方法 void run()`: 用于让子类重写, 表示该线程要执行的任务. 不能直接调用 void start(): 启动线程, 即让线程开始执行run()`方法中的代码 String getName()`: 获取线程的名称 void setName(String name)`: 设置线程名称 静态方法 static Thread currentThread()`: 返回对当前正在执行的线程对象的引用 static void sleep(long millis)`: 让所在线程睡眠指定的毫秒 多线程实现方式1: 定义类, 继承Thread类, 重写run()方法 步骤: 定义一个类, 继承Thread类 在子类中重写父类的run()方法 创建子类的对象 调用子类对象的start()方法启动线程
main()方法也是执行在一个线程中的,是单线程的, 方法中的代码是一行一行向下执行的 创建线程的第二种方式:实现Runnable接口 实现Runnable接口, 重写run()方法 步骤 多线程中的线程安全问题: 使用同步代码块去解决共享资源问题 同步:多个线程在执行同步的代码时,程序只能按照顺序一个一个去执行 优点:同步安全性高,效率低 同步代码块: 使用synchronized修饰的代码块 作用: 被同步代码块包裹的代码相当于在一个房间内, 锁对象相当于房间的锁 一个线程进入同步代码块, 会把门锁上, 同步代码块外面的线程看到同步代码块内部有线程, 只能在外面等待 直到同步代码块内部的线程执行完毕从代码块中出来, 释放了锁, 外面等待的线程才能随机进去一个 应用位置: 哪些代码属于共享操作, 需要避免安全问题, 就将这些代码放入同步代码块 术语 线程进入同步代码块, 叫获取锁 线程出同步代码块, 叫释放锁 锁是一个任意类型的对象,必须是被所有线程共享的,同步代码块必须配合所对象来使用 出现多线程的安全问题, 检查一下2个方面 对于操作了了共享数据的代码是否是同步的? 同步使用的是否是同一个锁对象?
继承Thread 类和实现Runnable接口在共享资源上有啥区别? 继承Thread类: Thread类中的非静态变量成员变量是每个线程各自拥有的,不能作为共享资源 静态成员变量是所有线程对象共享的,可以作为共享资源 实现Runnable接口: 如果所有的Thread对象都传入同一个Runnable对象,那么 Runnable对象中的非静态成员变量会被所有线程共享,可以作为共享资源 Runnable对象中的静态成员变量也会被所有Thread对象共享,也可以作为共享资源 所以, 继承Thread类方式下,共享资源要定义成Thread类的静态资源 实现Runnable接口方式下,共享资源要定义为Runnable接口的静态或非静态资源,并且所有Thread对象都要传入同一个Runnable对象 线程的生命周期 线程的生命周期中有5种状态 创建: new一个线程对象, 此时还没有调用start() 就绪: 调用start()方法后, 进入就绪状态, 等待CPU执行 运行: 获取了CPU的执行权, 开始运行线程 阻塞: 调用了sleep(), wait(), 或由于IO操作导致阻塞. 阻塞解除后仍会返回就绪状态, 等待CPU执行 销毁: 线程执行完毕
线程之间的通信 wait():使当前此案成处于等待状态,并且会立刻释放锁 notify():随机唤醒一个处于等待状态的线程 notifyAll(): 唤醒全部处于等待状态的线程 注意:这三个方法必须在同步代码块中,且只能用锁对象来调用,否则会抛异常 sleep()和wait()有啥区别? sleep() : 让当前的线程在指定的时间睡眠, 时间结束后就继续执行.不会释放锁 wait(): 让当前线程等着,知道有人唤醒,会立刻释放锁 线程释放锁的3种情况 死锁?????? 死锁: dead lock 同步代码块中的线程不出来, 也不释放锁; 同步代码块外的线程拿不到锁, 只能等在外面. 发生死锁的原因: 同步代码块内的线程, 可能处在死循环, IO阻塞, sleep()状态, 导致内部持有锁的线程无法出同步代码块 多个线程互相持有锁又不释放锁: 两个线程执行的任务都是双层同步代码块, 每层同步都需要一个锁, 两个线程中同步代码块的锁是相反的
死锁的结果: 程序卡死, 无法继续执行 怎么避免死锁: 避免在同步代码块中执行死循环, IO阻塞操作, sleep() 避免多个线程互相持有锁又不释放锁的情况 另一种加锁方式: Lock类 // 创建锁对象, 该锁对象也要所有线程共享唯一一个private Lock lock = new ReentrantLock(); lock.lock(); // 加锁, 相当于执行到synchronized// 同步的代码lock.unlock(); // 释放锁, 相当于同步代码块执行完毕网络
day12网络网络编程概述网络编程: Socket : 中文译名为 套接字 对协议的一个封装 用于描述IP地址和端口,时一种网络编程机制,通信两端都有Socket 网络通信三要素传输协议: 通信的规则 作用:通信的规则 常见协议: TCP// 传输控制协议 : 需要建立链接的可靠协议 没有数据传输大小的概念 在传输前需要先建立连接(三次握手) 重发机制, 如果接收方没有接收到信息,发回验证信息,然后发送方会重新发送 所以数据发送时间长,数据流量大 使用场景: 适合准确性要求强的场合,比如金融系统,视频点播(可缓冲) 形成传输数据的通道,通过三次握手完成链接,可靠协议,效率低 UDP// 用户数据报协议: 无连接的不可靠的协议 数据传输大小限制为64K(一个包) 不需要建立连接随便扔 数据发送速度快,发送方只管发送数据,不管你接没接到,所以可能又丢包情况 使用场景: 适合实时性要求强的场合,QQ语音,微信视频,卡掉就是卡掉了,中间空白了 IP 可以使用主机名或域名代替,更容易记忆 端口号: 作用: 标识使用网络通信的进程的逻辑地址,用于定位一个主机上的具体服务 端口号范围: 0 - 65535 前1024个端口时系统保留的端口号 常见服务占用的端口 80: HTTP服务 443: HTTPS服务,安全加密的HTTP 21: FTP服务,文件传输 22: SSH服务,安全加密的远程登陆 23: Telnet服务,远程登陆 举例理解三要素(寄快递) 传输协议:用什么快递 IP地址: XX省XX市XX街道XX号 端口号: X楼 InetAddress概述和测试java.net.包下InetAddress类: 用于表示IP地址对象(包含IP地址和主机名) static InetAddress getLocalHost() :获取本机的InetAddress对象 getByName():根据主机名或IP的字符串获取主机对象 getLoopbackAddress(): 获取回环地址的InetAddress的对象, static InetAddress getByAddress(byte[] addr): 根据IP获取InetAddress对象 getHostName(): 获取主机名 getHostAddress(): 获取IP地址 getLocalHost(): 获取本机主机名 ipconfig: 在cmd中输入用于查看本机的IP信息UDP协议发送数据DatagramSocket : 基于UDP协议的Socket 构造方法: DatagramSocket(): 创建Socket对象并随机分配端口号 DatagramSocket(int port) : 创建Socket对象并指定端口号 成员方法: send(DatagramPacket p): 发送数据包 receive(DatagramPacket p ): 接收数据,数据保证在DatagramPacket对象中 close(): 关闭通信,释放资源 DatagramPacket 类: UDP数据包 构造方法: DatagramPacket(byte[] msg, int msgLength, InetAddress host, int port): 创建数据包对象, 指定数据, 目标主机对象, 端口 DatagramPacket(byte[] buf,int length):创建数据包对象,接收数据为length的数据,存入byte数组中 成员方法 InetAddress getAddress(): 获取数据包发送方的InetAddress对象 byte[] getData(): 获取包中的数据, 以byte数组形式 int getLength(): 获取数据的长度, 即byte数组的长度 int getPort(): 获取发送方端口号
UDP协议接收数据端口号错误,数据可以正常发出,不会出现异常,但是收不到数据 BindException : 端口绑定异常 端口号不能重复, TCP协议发送数据构造方法: Socket(InetAddress add, int port): 创建TCP客户端对象 成员方法: OutputStream getOutputStream(): 获取输出流对象, 用于发送数据 InputStream getInputStream(): 获取输入流, 用于接收数据 void close(): 释放资源 TCP发送数据步骤 - // 1. 创建客户端Socket对象(建立连接)Socket socket = new Socket(InetAddress地址, 端口号);// 2. 获取输出流对象OutputStream outputStream = socket.getOutputStream();// 3. 发送数据outputStream.write(byte数组);// 4. 释放资源socket.close();TCP协议接收数据
java.net.ServerSocket`: TCP服务端
构造方法
成员方法
Socket accept(): 监听数据, 会阻塞. 收到数据后返回Socket对象 void close(): 关闭Socket 反射Reflect反射:Reflect 在运行时,我们可以获取任意一个类的所有方法和属性(包括私有的) 在运行时,让我们调用任意一个对象的所有方法和属性(包括私有的) 反射的前提:要获取类的对象(Class对象) 获取字节码对象的三种方式 //建立了一个student类
通过Object的getClass()方法获取,必须有对象 student s = new student(); Class clazz = s.getClass; 通过类名获取字节码对象 Class clazz = Student.class; static Class<?> forName(String className) Class clazz = Class.forName(" 全部的类名") 反射获取构造方法并创建对象反射使用的相关类和方法java.lang.Class类: 类的字节码对象 获取构造方法: Constructor<?>[ ] getConstructors(): 以数组形式返回该类中的所有public的构造方法,如果没有public的,则数组长度长度为0 Constructor<?>[ ] getDeclaredConstructors(): 以数组形式返回该类中所有权限的构造方法,包括私有的,如果该类时接口,基本类型,数组,void,则数组长度为0 Constructor<?>[ ] getConstructors(Class<?>... parameterTypes): 根据参数列表返回指定的public的构造方法,参数列表填写参数的字节码对象 Constructor<?>[ ] getDeclaredConstructors(Class<?>... parameterTypes):根据参数列表返回指定的所有权限的构造方法,包括私有的,参数列表填写参数的字节码对象
创建对象: T newInstance() 反射获取public成员变量:设置和获取值成员变量方法:getFields(): 获取公共的成员变量 getFields(): 获取所有public的成员变量 getDeclaredFields(): 获取所有权限的成员变量.包括私有的 getFields(String fieldName): 通过指定的成员变量名获取指定的punlic成员变量 getDeclaredFields(String fieldName): 通过指定的成员变量名获取指定的所有权限的成员变量.包括私有的 成员变量对象:Object get(Object obj): 获取指定对象的属性值,传入对象,返回该对象的属性 反射获取成员方法并调用获取成员方法: Method [ ] getMethods(): 返回所有public的方法数组 Method [ ] getDeclaredMethods(): 返回所有权限的方法数组 Method getMethods(String name,Class<?>... parameterTypes): 获取public的方法,传入方法名和方法形参字节码对象
HTML :超文本标记语言扩展名为.html 或者.htm 空格:&npsp <hr/ > 横线 <pre>:原生标签,把copy过来的内容原封不动的粘过来 字体标签<font>文字</font> <font>标签的属性: color:字体的颜色 size:字体的大小 face: 字体 标题标签<h1>...<h6> 段落标签<p> 粗体标签<b> 斜体标签<i> 下划线标签<u> 居中显示<center> 图片标签<img>属性: src: 图片的来源路径 width: 图片的宽度 height: 图片的高度 alt:图片找不到显示的内容 图片引入的路径问题? 路径:相对路径 同一路径可以直接写文件名或 ./ 文件名 上一级目录: ../ 列表标签有序列表<ol> <li></li> </ol> type属性 : 1 数字类型 a 英文类型 i 罗马字符 start : 从哪里开始, 无序列表<ul> <li></li> </ul> type属性: disc :实心点 circle:空心圆 square:方块 超链接标签<a> 属性: href: 链接的路径 target: 打开的方式 _self : 在自身页面打开 _blank : 新打开一个窗口 _parent : 表格标签<table> <tr> :行 <td> :列 属性: width: 表格宽度 height:表格高度 border: 边框 aligh: 表格水平位置: left :居左 right: 居右 center:居中 <td>的属性: 合并表格: colspan = "列数" rowspan = "行数" HTML的表单标签<from>常用属性:action属性: 提交的路径,如果没指定默认提交到当前页面 method属性: 请求的方式,GET和POST,默认是GET 常问的面试题:GET和POST属性的区别? GET: 数据会显示到地址看重 , 提交是有大小限制的,请求行里边 POST: 数据不会显示到地址栏中 . 相对来说安全一点,提交没有大小限制,请求体中 <input type = "text"> :文本框 name : 表单名称,要有名字方便后台接收 value : 文本框的默认值 size : 设置文本框的长度 maxlength : 设定几个数字 就只能接收几个数字 readonly : 不允许输入的.只读的 <input type = "password"> :密码框 name : 表单名称,要有名字方便后台接收 value : 文本框的默认值 size : 设置文本框的长度 maxlength : 设定几个数字 就只能接收几个数字 <input type = "radio"> :单选按钮 name : 表单名称,要有名字方便后台接收 value :单选按钮的默认值 checked : 单选按钮默认被选中 <input type ="checkbox"> :复选框 name : 表单名称,要有名字方便后台接收 value :单选按钮的默认值 checked : 单选按钮默认被选中 <input type ="button"> :普通按钮<input type ="submit"> :提交按钮<input type ="reset"> :重置按钮<input type ="file"> :文件上传(可浏览上传)<input type ="hidden"> :隐藏字段<input type ="image"> :图片按钮<select> : 下拉列表<textarea> : 文本域HTML5扩展的表单标签(不是所有浏览器都支持)<input type = "email"> :只能输入邮箱形式的 <input type = "date"> :只能输入日期形式的 <input type = "number"> :只能输入数字 <input type = "color"> :颜色板 可以直接选 此致......
|