黑马程序员技术交流社区

标题: 【石家庄校区】这又是一篇学习笔记 [打印本页]

作者: 空降的蛙崽    时间: 2018-4-23 16:05
标题: 【石家庄校区】这又是一篇学习笔记
本帖最后由 小石姐姐 于 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()方法
步骤:
main()方法也是执行在一个线程中的,是单线程的, 方法中的代码是一行一行向下执行的
创建线程的第二种方式:实现Runnable接口
实现Runnable接口, 重写run()方法
步骤
多线程中的线程安全问题: 使用同步代码块去解决共享资源问题
同步:多个线程在执行同步的代码时,程序只能按照顺序一个一个去执行
优点:同步安全性高,效率低
同步代码块: 使用synchronized修饰的代码块
作用:
被同步代码块包裹的代码相当于在一个房间内, 锁对象相当于房间的锁
一个线程进入同步代码块, 会把门锁上, 同步代码块外面的线程看到同步代码块内部有线程, 只能在外面等待
直到同步代码块内部的线程执行完毕从代码块中出来, 释放了锁, 外面等待的线程才能随机进去一个
应用位置:
哪些代码属于共享操作, 需要避免安全问题, 就将这些代码放入同步代码块
术语
线程进入同步代码块, 叫获取锁
线程出同步代码块, 叫释放锁
锁是一个任意类型的对象,必须是被所有线程共享的,同步代码块必须配合所对象来使用
出现多线程的安全问题, 检查一下2个方面
继承Thread 类和实现Runnable接口在共享资源上有啥区别?
继承Thread类: Thread类中的非静态变量成员变量是每个线程各自拥有的,不能作为共享资源
静态成员变量是所有线程对象共享的,可以作为共享资源
实现Runnable接口: 如果所有的Thread对象都传入同一个Runnable对象,那么
Runnable对象中的非静态成员变量会被所有线程共享,可以作为共享资源
Runnable对象中的静态成员变量也会被所有Thread对象共享,也可以作为共享资源
  所以, 继承Thread类方式下,共享资源要定义成Thread类的静态资源
实现Runnable接口方式下,共享资源要定义为Runnable接口的静态或非静态资源,并且所有Thread对象都要传入同一个Runnable对象
线程的生命周期
线程的生命周期中有5种状态
线程之间的通信
wait():使当前此案成处于等待状态,并且会立刻释放锁
notify():随机唤醒一个处于等待状态的线程
notifyAll(): 唤醒全部处于等待状态的线程
注意:这三个方法必须在同步代码块中,且只能用锁对象来调用,否则会抛异常
sleep()和wait()有啥区别?
sleep() : 让当前的线程在指定的时间睡眠, 时间结束后就继续执行.不会释放锁
wait(): 让当前线程等着,知道有人唤醒,会立刻释放锁
线程释放锁的3种情况
死锁??????
死锁: dead lock
同步代码块中的线程不出来, 也不释放锁; 同步代码块外的线程拿不到锁, 只能等在外面.
发生死锁的原因:
死锁的结果: 程序卡死, 无法继续执行
怎么避免死锁:
避免在同步代码块中执行死循环, IO阻塞操作, sleep()
避免多个线程互相持有锁又不释放锁的情况
另一种加锁方式: Lock类
// 创建锁对象, 该锁对象也要所有线程共享唯一一个private Lock lock = new ReentrantLock();
lock.lock();    // 加锁, 相当于执行到synchronized// 同步的代码lock.unlock();  // 释放锁, 相当于同步代码块执行完毕网络
day12网络网络编程概述
网络编程:
Socket :  中文译名为        套接字      对协议的一个封装
用于描述IP地址和端口,时一种网络编程机制,通信两端都有Socket
网络通信三要素
传输协议:  通信的规则
​                作用:通信的规则
​                常见协议:  
TCP// 传输控制协议 :
​        需要建立链接的可靠协议
​        没有数据传输大小的概念
​        在传输前需要先建立连接(三次握手)
​        重发机制, 如果接收方没有接收到信息,发回验证信息,然后发送方会重新发送
​        所以数据发送时间长,数据流量大
使用场景: 适合准确性要求强的场合,比如金融系统,视频点播(可缓冲)
形成传输数据的通道,通过三次握手完成链接,可靠协议,效率低
UDP// 用户数据报协议:
         无连接的不可靠的协议
​        数据传输大小限制为64K(一个包)
​        不需要建立连接随便扔
​        数据发送速度快,发送方只管发送数据,不管你接没接到,所以可能又丢包情况
使用场景:
​        适合实时性要求强的场合,QQ语音,微信视频,卡掉就是卡掉了,中间空白了
​        
IP地址 : 是一个二进制数字    如www.badu.com 会通过DNS 查询IP地址
​        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数组中
成员方法
UDP协议接收数据
端口号错误,数据可以正常发出,不会出现异常,但是收不到数据
BindException : 端口绑定异常  端口号不能重复,
TCP协议发送数据
构造方法: Socket(InetAddress add, int port): 创建TCP客户端对象
成员方法:









欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2