标签:迅雷 网吧上网 接口 object类 final 案例 区别 改名 多线程
JAVA17
l 正在运行中的程序
l 程序存储在硬盘中 当进入内存运行时
l 内存中的每一个程序就叫进程
l 并且每一个进程都有一个独立的功能
l 迅雷中的多线程下载
l main方法中有很多方法一次排列
l 例如
多台电脑网吧上网
多条路通行
l CPU 中央处理器 inter AWD
l 四核心 八线程
l 360杀毒工具
l 多线程下载
l 并不是提高了网速 而是多线程提高了速度
l 所有线程轮流使用cpu资源 平均分配对个线程占用CPU时间
l 优先级高的多使用cpu资源 优先级相同的随机选择一个进行调度
l
l 编译
l JVM运行main方法
l 找操作系统 开线程
l 对于cpu有了一个执行的路径 运行方法main路径有个名字main
l 这个就是主线程
l 多线程就算一条线程出现错误 其他线程也会执行
l Java.lang包中
l Jvm允许程序运行多个线程
l 每一个线程都有一个优先级
l 创建线程有两个方法
l 定义一个类继承Thread 重写run方法
l 在测试类中实例化这个类的对象 调用start方法
l Start方法只能执行一次
l 执行顺序跟之前不一样
l 图解
l 调用run和start区别
l Thread是线程类 继承这个类就是 线程类
l 直接创建Thread类对象,run方法是这个类的方法,没有任何操作 不能运行自定义的代码 所以需要继承这个类 重写run方法然后执行我们需要在另一个线程中执行的代码
l Run方法的作用是为了执行我们要在新线程中执行的代码
l Main方法先进入
l 然后调用start方法 run方法准备被jvm调用
l Run方法不进入这个栈 会新开一个栈空间单独执行run方法
l
l main主线程名称就是 main
l 控制台获取默认线程名字
l getName获取线程名
调用父类方法可以不写super
l 获取main线程名字
Static Thread currentThread();
获取正在运行本方法的线程名字 返回Thread类型
简化
l setName()
l 构造方法改线程名
l 线程停止特定时间
l 抛异常
因为休眠过程中被唤醒会抛此异常
l 实现线程的的另一种方式
l 实现接口Runnable
l 实现方法run
l 前提 继承或接口实现
l new 父类或者接口实现(){ 重写抽象方法 }
l 示例
l NEW 新建状态
l RUNNABLE 运行状态 正在JVM虚拟机中执行此线程
l BLOCKED 受阻塞
死锁 CPU资源被抢走
l WAITTING 等待 无限休眠
Object类中的方法
l TIMED_ WAITTING 休眠
l TREMINATED 死亡状态
l 受阻塞具有cpu的执行资格 等待CPU的资源
l 休眠等待 线程放弃CPU的执行资格
l 是一个容器可以存放多个线程
l 程序一开始的时候 创建多个线程 存放到集合中
l 使用时 用remove方法取出线程 使用完毕 再用add重新添加进去
l 之前都是自己开发线程池
l Jdk1.5之后添加了线程池技术
l 由线程池工厂创建
l 再调用线程池中的方法创建线程
l Executors类
a) 创建多个
b) 创建单个
c) 返回值是线程池类对象
控制台没停止 线程用完后有回到了线程池
线程名字
停止线程
Shutdown 线程停止
l Runnable接口 线程运行完没有结果 不能抛异常
l Jdk1.5后有个Callable接口 call方法 等同于run
l call方法有返回值 可以抛异常
l 先用工厂类静态方法newFixedRhreadPool创建线程池对象
l 线程对象 调用方法submit提交线程任务 传入一个Callable接口实现类
l 示例
父类接口抛了异常 子类可抛异常也可不抛异常
l 异步计算
l 多个线程同时运行 同时运行某段代码
l 每次运行结果和单线程运行结果一样
l 售票
l 多种方式购票 多个线程操作同一个数据
l 此时应该数据同时更新 否则会出现安全问题
l 示例
数据正常 但是存在安全隐患
l T0判断完毕 准备开始操作
l 此时cpu被t1线程抢占
l T1判断完毕 准备进行操作
l 此时被t2线程抢占
l T2判断完毕 准备进行操作
l 此时cpu资源获得 t0执行操作 – 数据为0
l T1也执行—数据为-1
l T2也执行--数据为-2
l 此时出现了线程安全问题
l 模拟示例
Synchronzied(任意对象){
线程操作的共享数据
}
不能写匿名对象
变得安全了
但是速度变慢了
l 同步对象 任意对象
l 对象 :同步锁 对象监视器
l 同步保证安全性 没有锁的线程不能执行 只能等
l 线程遇到同步代码块后 判断同步锁还有没有
l 如果没有就等待
l 如果有 获取锁 将同步锁设为0
l 进入同步代码块 此时如果休眠了
l 另一个线程过来 要执行代码 会判断同步锁是否有 此时显然是没有的 因此就进不去代码块 不能执行代码
l 此时如果第一个线程 唤醒了 就继续执行代码 然后释放同步锁
l 因此一个线程需要判断锁 获取锁 释放锁 所以就延长了很长时间
l 同步锁原理和上厕所
l 多个线程访问一个共享数据就要设置同步锁
l 代码简洁
l 将线程共享数据和同步抽取到一个方法中
l 方法的声明加上同步关键字 然后把同步不代码块删除
l StringBuffer 就有这种同步方法 跑的慢
l StringBuilder 是线程不安全 跑的快
l 同步方法有锁吗?
l 如果方法是静态的
l 释放同步锁 看不到
l 如果代码出现异常 锁就不会释放
l 因此JDK1.5后出现了Lock接口
l 此接口提供了比使用synchornized更多的方法和语句可获得的跟广泛的锁定操作
l 示例
lock 获取锁
unlock 释放锁
ReentrantLock
l 同步锁里面又写了一个同步
l 程序中出现了无限等待
l 前提必须是多线程出现同步嵌套
l 线程进入同步获取锁 不出去同步不会释放锁
l 第一个人需要第二个人的锁 第二个人有需要第第一个人的锁
l
l 定义两个锁对象 A B
l 循环用奇数偶数确定线程1 和线程2
l 然后一个测试类
l 程序运行结果 程序永远都不会停止运行
l 又叫线程通信
l 多个线程处理同一个资源
l 每个线程任务不一样
l 如果要合理的运用资源
l 就需要通过一种手段使各个线程能有效的利用资源
l 这种手段就叫做 等待唤醒机制
l 比如售票 之前只是减票 现在有的线程需要加票
l 资源类
l 两个线程类 输入 输出
l 测试类
因为有两个对象
l 解决
l 解决
a) 输入类抢到了cpu 进行赋值 张三 男
b) 赋值 完 输出没有抢到cpu
c) 输入类仍然抢到了cpu 进行赋值 lisi
d) 刚赋值完lisi 还没赋值nv
e) 输出类抢到了cpu资源 就直接输出 了 lisi nv
f) 此时就出现了 性别乱套
a) 只有一种方法加同步锁
b) 找共享数据
c) 在输入类中加锁
输出类加入锁
还是没解决
l 解决
a) 两个线程是不是同一个锁
l 最终目标 一个输入 一个输出 交替出现
l 线程只会执行run方法 不分赋值和取值
l 理想状态应该是 一次赋值一次打印
l 只有上一次赋值输出后 下一次赋值才能开始
l 反过来 输出一次后 必须等待下一次输入完毕后才能进行输出
l 实现步骤
l 为了保证程序执行 输入首先拿到cpu执行权
l 在资源类中加一个变量boolean flag
l flage为真 说明赋值完成
l flage为假 说明获取值完成
l 输入 需要判断标记 flage是否为真
如果为真 则等待
如果为假 就进行赋值 并把标记改为false
l 输出也是如此
l 示例
输入
输出
结果 抛出了异常
异常
就是说唤醒和等待方法 调用者错了
应该是锁对象 调用
修改
l 结果
标签:迅雷 网吧上网 接口 object类 final 案例 区别 改名 多线程
原文地址:http://www.cnblogs.com/DMYMaster/p/7293783.html