Java核心开发-14【多线程】

上传人:飞****9 文档编号:130081971 上传时间:2020-04-24 格式:PPT 页数:29 大小:993.50KB
返回 下载 相关 举报
Java核心开发-14【多线程】_第1页
第1页 / 共29页
Java核心开发-14【多线程】_第2页
第2页 / 共29页
Java核心开发-14【多线程】_第3页
第3页 / 共29页
Java核心开发-14【多线程】_第4页
第4页 / 共29页
Java核心开发-14【多线程】_第5页
第5页 / 共29页
点击查看更多>>
资源描述

《Java核心开发-14【多线程】》由会员分享,可在线阅读,更多相关《Java核心开发-14【多线程】(29页珍藏版)》请在金锄头文库上搜索。

1、 Java多线程和并发 第十四章 本章目标 什么是多线程中断线程线程状态线程属性同步死锁 什么是多线程 我们来看下熟悉的windows操作系统 它是多任务的 在同一时刻有多个程序在同时运行 多线程就是引入了多任务的思想 单个程序看起来可以同时处理多个 任务 这个任务被称之为线程 Let sGo 看一个多线程的程序感受下 什么是多线程示例 publicstaticvoidmain String args Model1 定义二个线程 并调用它们Threadt1 newThread newThreadTest1 线程一 Threadt2 newThread newThreadTest1 线程二 t1

2、 start t2 start Model2 没有使用线程调用情况 ThreadTest1t1 newThreadTest1 线程一 ThreadTest1t2 newThreadTest1 线程二 t1 run t2 run 分别执行Model和Model2 看看输出结果 第一个多线程输出 第二个单线程输出 publicclassThreadTest1implementsRunnable privateStringthreadName 线程名称publicThreadTest1 StringthreadName this threadName threadName publicvoidrun

3、 try inti 0 一个死循环输出计数 每次加1while true Thread sleep 1000 每个1秒钟输出一次System out print 当前线程名称 threadName System out print 计数 i if i 10 break 退出循环 catch Exceptione 如何创建线程 继承Thread类或者实现Runnable接口重写run方法调用start 方法启动线程 线程中断 在JDK1 0时代 有个stop 方法可以终止线程 目前已经被废弃了 现在没有强制终止线程的方法了 但是可以使用interrupt来请求中断线程如何使用呢 我们在刚刚的例子

4、里修改下一般来讲 中断线程操作通常放在异常处理中去做 if Thread currentThread isInterrupted 线程方法小结 Thread已经学习的方法start 启动线程run 必须重载这个方法 里面放线程处理代码interrupt 发送中断请求 如果当前线程sleep了 则抛出InterruptException异常isInterrupt 检查线程是否已经被中断了currentThread 返回代表当前执行的线程 线程状态 New 新生 使用了new操作符创建一个线程之后Runnable 可运行 调用了start方法之后Blocked 被阻塞 调用了sleep方法线程调用

5、一个在I O上被阻塞的操作有人调用了suspend方法Dead 死亡 run方法正常退出死亡发生异常终止了run方法而使线程死亡 线程调度图 线程调度示例图 线程方法小结 Thread增加一些方法isAlive 线程已经启动且没有终止 则返回truestop 停止线程 已过时suspend 挂起当前线程执行过程 已过时resume 恢复线程 在suspend之后用 已过时join 等待直到指定的线程死亡join longmillis 等待直到指定的线程死亡或经过指定毫秒数 线程属性 在这里我们将要讨论的内容线程优先级守护线程线程组 线程优先级 在Java中 每个线程都有优先级可以使用setPr

6、iority方法进行设置MIN PRIORITY 在Thread中定义为1 MAX PRIORITY 在Thread中定义为10 NORM PRIORITY 在Thread中定义为5 示例演示 守护线程 什么是守护线程 守护线程的唯一作用就是为其他线程提供服务 例如计时器线程就是一个例子当只剩下守护线程时 就没有运行程序的必要了通过setDaemon booleanisDaemon 设定该方法必须在线程开始执行之前调用 线程组 按照功能对线程进行分类 类别即为线程组根据ThreadGroup类创建要查明某个线程组中是否有线程处于可运行状态要中断线程组中所有线程 StringgroupName

7、浏览器线程组 ThreadGroupg newThreadGroup groupName 创建线程组Threadt newThread g threadName 创建线程 If g activeCount 0 allthreadsinthegroupghavestopped g interrupt 中断线程组中所有线程 线程小结 如何创建线程继承Tread类或实现Runnable接口 重写run 方法线程状态新生 可运行 被阻塞 死亡线程优先级守护线程线程组 线程示例演示 同步 在实际应用中 通常会遇到多个线程对相同资源进行共享访问 比如2个线程 它们都对同一对象进行访问 根据它们访问银行账号

8、的不同顺序 就有可能产生腐蚀的对象 这就叫做竞争条件 示例演示 同步 假设我们有个Bank类 它有个方法 模拟将一定数额的钱从一个账户转移到另一个账户中 publicvoidtransfer intfrom intto doubleamount if accounts from amount return 金额不够不允许转出System out print 执行线程 Thread currentThread getName accounts from amount System out print 从 from 转出到 to 中 转出金额为 amount accounts to amount

9、System out println 银行总金额为 getTotalBalance publicvoidrun while true inttoAccount int bank size Math random doubleamount maxAmount Math random bank transfer fromAccount toAccount amount 同步 结果发现 开始总金额还是一致的 后来银行总金额变了 这就叫做腐蚀对象问题出在哪里了呢 假如两个线程同时执行accounts to amount我们分解这段代码将accounts to 载入寄存器增加amount将结果写回acc

10、ounts to 假设线程1执行了第一步 第二步后中断了 此时线程2更新了accounts数组中同一项 接着线程1被唤醒并完成了第三步 这时 线程2所做的更新被抹去了 同步 怎么解决这个比较严重的问题呢 ReentrantLock类 JDK1 5之后才出现的synchronized关键字 在Bank类中新增一个如下属性privateLockbankLock newReentrantLock 修改transfer方法publicvoidtransfer intfrom intto doubleamount bankLock lock try 刚刚transfer的方法内容 finally ban

11、kLock unlock 条件对象 当一个线程进入临界区 发现它必须满足某个条件后才能执行 这就需要你使用条件对象来管理在我们刚刚transfer方法中有一行如下代码其实我们不能这么写 应该让线程进入等待状态 当满足条件的时候再继续运行 if accounts from amount return 金额不够不允许转出 bankLock lock try while accounts from amount wait 执行 finally bankLock unlock 条件对象 在Bank类中新增一个如下属性privateConditioncondition 在构造函数中初始化它Conditi

12、on bankLock newCondition 修改transfer方法publicvoidtransfer intfrom intto doubleamount bankLock lock try while accounts from amount condition await condition signalAll finally bankLock unlock Synchronized关键字 在方法返回值之前加上synchronized条件对象 利用Object类中wait 和notifyAll publicsynchronizedvoidtransfer intfrom intt

13、o doubleamount Publicsynchronizedvoidtransfer intfrom intto doubleamount while accounts from amount wait notifyAll 同步快 举例说明 如果该方法被调用 它会获取所关联类对象的锁 也就是说它被调用时 Bank class对象的锁会被锁住 Publicvoidtransfer intfrom intto doubleamount synchronized this accounts from amount accounts to amount 修改后的线程调度图 死锁 锁和条件不能解决

14、多线程中的所有问题 比如下列情况 账户1 200 账户2 300 线程1 把 300从账户1转到账户2 线程2 把 400从账户2转到账户1 2个线程都会被阻塞 谁都无法执行 因为2个账户中余额都不足 这就叫做死锁修改我们同步的例子 在main方法中修改 就会死锁 TransferRunnabler newTransferRunnable b i 10000 死锁 很遗憾 在Java中没有任何东西能够避免或打破这种死锁现象 你必须仔细的设计你的程序以确保死锁不会发生 同步小结 什么叫腐蚀对象如何解决腐蚀对象 利用同步synchronized关键字ReentrantLock类条件对象Object

15、类中wait 和notify 方法Condition类中await 和signalAll 方法死锁 作业 作业1 有5个哲学家 他们的生活方式是交替地进行思考和进餐 哲学家们共用一张圆桌 分别坐在周围的五把椅子上 并在圆桌上有五支碗和五支筷 每两个哲学家之间一根筷子 哲学家思考的时候不影响别人 饥饿的时候就会拿左右两根筷子进餐 进餐毕 放下筷子 请用Java程序模拟它 并防止出现死锁现象 定义两个类 Philosopher 哲学家 Chopsticks 筷子 Philosopher类包含进餐 思考等方法Chopsticks定义ints 0 0 0 0 0 0表示筷子未占用 1表示被占用 以及两个方法拿起筷子 放下筷子主函数生成5个线程表示5个哲学家作业2 查查我们所学过的集合框架哪些是同步的 谢谢

展开阅读全文
相关资源
相关搜索

当前位置:首页 > IT计算机/网络 > 其它相关文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号