欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > PPT文档下载  

    996-第十三章 并发.ppt

    • 资源ID:3026208       资源大小:170.01KB        全文页数:50页
    • 资源格式: PPT        下载积分:6
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要6
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    996-第十三章 并发.ppt

    1,第十三章 并发,2,线程的概念 线程的创建 线程调度与线程控制 线程同步 线程状态与生命周期,3,什么是线程,多线程是实现并发的一种有效手段。 一个进程可以通过运行多个线程来并发地执行多项任务。 多个线程如何调度执行由系统来实现。,4,什么是线程,线程是程序中的单个执行流,多线程是一个程序 中包含的多个同时运行的执行流。,5,线程与进程,进程:内核级的实体。包含虚存映象、文件指示符, 用户ID等。这些结构都在内核空间中,用户程序 只有通过系统调用才能访问与改变。 线程:用户级的实体。线程结构驻留在用户空间中, 能够被普通的用户级函数组成的线程库直接访问。 寄存器(栈指针,程序计数器)是线程专有的成分。 一个进程中的所有线程共享该进程的状态。,6,一个虚拟的CPU,,代码所操作的数据:数据也可以 被多个线程共享。,该CPU执行的代码: 代码与数据是相互独立的,代 码可以与其它线程共享。, Java 中线程被认为是一个CPU、程序代码、和数据 的封装体。,Java中的线程,7, Java.lang.Thread类使用户可以创建和控制自己的线程。 在Java中,虚拟CPU是自动封装进Thread类的实例中, 而Code和Data要通过一个对象传给Thread类的构造函数。,线程的构造,8,线程的创建, 线程的Code和Data构成线程体。线程体决定了线程的行为。 Java中线程体由Thread类的 run( ) 方法定义,该方法 定义了线程的具体行为并指定了线程要操作的数据。 有两种方式进行run( )方法的定义: 实现 Runnable 接口 继承 Thread 类,9, Runnable 接口只提供了一个public void run( )方法。 定义一个类实现Runnable接口。 将该类的实例作为参数传给Thread类的一个构造函数, 从而创建一个线程。,通过实现Runnable 接口创建线程,10,Public class ThreadTest public static void main(String args ) Xyz r= new Xyz( ); Thread t = new Thread( r ); t.start( ); Class Xyz implements Runnable int I ; public void run( ) while( true) System.out.println(“Hello”+I+); if (I=5) break ; ,线程创建示例,11,线程 t,Xyz类,Xyz的实例 r,一个线程就是Thread类的一个实例。 线程是从一个传递给线程的Runnable 实例的run( )方法开始执行。 线程所操作的数据是来自于该 Runnable 类的实例。,线程创建示例,12,通过继承Thread类创建线程, Thread 类本身实现了Runnable接口。 通过继承Thread类,重写其中的run( )方法定义线程体。 创建该子类的对象创建线程。 Public class Counter extends Thread public void run( ) 创建与运行线程: Counter ThreadCounter = new Counter( ); ThreadCounter.Start( );,13,线程两种创建方法比较,实现Runnable接口的优势: 符合OO设计的思想。 便于用extends继承其它类。 采用继承Thread类方法的优点:程序代码更简单。 提倡采用第一种方式。,14,线程的运行,新创建的线程不会自动运行。必须调用线程的start( )方法, 如: t.start( ) 该方法的调用把嵌入在线程中的虚拟CPU置为可运行 (Runnable)状态。 Runnable状态意味着该线程可以参加调度,被JVM运行, 并不意味着线程会立即执行。,15,线程调度与线程控制,线程调度策略 线程的基本控制,16,线程调度策略, Java中线程调度采用抢先式调度方法。 抢先式调度模式: 许多线程可能是可运行的,但只能有一个线程在运行。 该线程将持续运行,直到它自行中止或出现高优先级 线程成为可运行的,则该低优先级线程被高优先级线程 强占运行。 线程中止的原因可能有多种,如执行Thread.sleep( )调用, 或等待访问共享的资源。,17,线程的优先级,每个线程都有优先级,有缺省值,可用 SetPriority( )方法改变。 每个优先级有一个等待池:,pool,pool,pool,t1,t2,t3,.,18,线程调度策略, JVM先运行高优先级池中的线程,待该池空后才 考虑低优先级线程。 如果有高优先级线程成为可运行的,则运行它。 抢先式可能是分时的,即每个池中的线程轮流运行; 也可能不是,即线程逐个运行,由JVM而定。 线程一般可用sleep( )保证给其他线程运行时间。,19,线程的基本控制,结束线程 获取当前线程 测试线程 sleep( ) join( ) yield( ),20,结束线程,线程完成运行并结束后,将不能再运行。 除正常运行结束外,还可用其他方法控制使其停止。 用stop( )方法。 强行终止线程,容易造成线程的不一致。 使用标志flag。 通过设置flag 指明run( )方法应该结束。,21,结束线程,class Xyz implements Runnable private boolean timeToQuit = false; public void run( ) while(!timeToQuit) / clean up before run() ends . public void stopRunning( ) timeToQuit = true ; public class ControlThread public void main(String args) Runnable r = new Xyz( ) ; Thread t = new Thread( r) ; t.start(); r.stopRunning( ); ,22,获取当前线程,Thread 类的静态方法currentThread( )返回当前线程。,23,测试线程,当线程的状态未知时,用isAlive( )确定线程是 否活着。返回true 意味着线程已经启动,但还没有 运行结束。,24,Sleep( )方法,该方法用来使一个线程暂停运行一段固定的时间。 在线程睡眠时间内,将运行别的线程。 Sleep( ) 结束后,线程将进入Runnable状态。,25,join( ) 方法,t.join( )方法使当前的线程等待,直到 t 结束为止,线程 恢复到runnable状态。,Public void doTask() TimerThread tt= new TimerThread(100) ; tt.start( ) ; / Do stuff in parallel with the other thread for a while / Wait here for the timer thread to finish try tt.join( ); catch( InterruptedException e) / tt came back early / continue in this thread ,26,yield( )方法,调用该方法将CPU让给具有与当前线程相同优先级 的线程。 如果没有同等优先级的线程是Runnable状态, yield( )方法将什么也不做。,27,线程同步,线程间同步机制 线程间的交互wait( ) 和notify( ) 不建议使用的一些方法,28,多线程并发执行中的问题,多个线程相对执行的顺序是不确定的。 线程执行顺序的不确定性会产生执行结果的不确定性。 在多线程对共享数据 操作时常常会产生这种不确定性。,29,多线程并发执行中的问题,一个堆栈类: public class MyStack private int idx = 0 ; private char data = new char6 ; public void push( char c ) dataidx = c ; idx + ; / 栈顶指针指向下一个空单元 public char pop( ) idx- ; return dataidx ; ,30,多线程并发执行中的问题,线程 a,线程b,堆栈 s 状态,时刻t1,时刻t2,时刻t3,/调用s.Push( ); dataidx=r ;,/恢复运行 idx+ ;,/*线程a 被抢占 idx+; 未执行*/,. . .,!“q”被两次压栈; 线程a 压入的数据“r”丢失。,31,对象锁的概念, Java中每个对象都带有一个monitor标志, 相当于一个锁。 Sychronized关键字用来给对象加上独占的排它锁。,32,对象锁的操作,Public void push(char c) synchronized(this) dataidx = c ; idx+ ; ,33,Code or behavior,Data or state,Object this,Thread after synchronized(this),Public void push(char c) synchronized(this) dataidx = c ; idx+ ; ,对象锁的操作,34,示例,将MyStack 对栈的push,pop操作都采用这种机制:,public class MyStack public void push( char c ) synchronized(this) dataidx = c ; idx + ; public char pop( ) synchronized(this) idx- ; return dataidx ; ,35,线程 a,线程b,堆栈 s 状态,时刻t1,时刻t2,时刻t3,/*调 用s.push( ), 获得s的monitor后运行*/ dataidx=r ;,/*调用s.pop(),未获得s的monitor, b到s的lock pool中等待*/,/恢复运行 idx+ ; 。 /*完成,并交回S的 monitor*/,/线程a 被抢占,. . .,多线程对共享数据进行操作,时刻t4,/运行pop 得结果r,36,几点说明,如何返还对象的monitor 当synchronized( ) 语句块执行完毕后。 当在synchronized( ) 语句块中出现exception. 当调用该对象的wait( )方法。将该线程放入 对象的wait pool中,等待某事件的发生。,37,几点说明,对共享数据的所有访问都必须使用synchronized. 用synchronized保护的共享数据必须是私有的,使线程 不能直接访问这些数据,必须通过对象的方法。 如果一个方法的整体都在synchronized块中,则可以把 synchronized关键字放于方法定义的头部: public synchronized void push( char c) ,38,几点说明,public class Reentrant public synchronized void a() b(); System.out.println(“here I am, in a()“); public synchronized void b() System.out.println(“here I am, in b()“); ,Java运行系统允许已经拥有某个对象所的线程再次获得该对象的锁Java locks are reentrant.,39,避免死锁,死锁是指两个线程同时等待对方持有的锁。 死锁的避免完全由程序控制。 可以采用的方法: 如果要访问多个共享数据对象,则要从全局考虑定义 一个获得封锁的顺序,并在整个程序中都遵守这个 顺序。释放锁时,要按加锁的反序释放。,40,线程间的交互, Wait( ) 和notify( ) 线程在synchronized块中调用x.wait( )等待共享数据 的某种状态。该线程将放入对象x的wait pool, 并且将释 放x的monitor。 线程在改变共享数据的状态后,调用x.notify(),则对象 的wait pool中的一个线程将移入lock pool,等待x的monitor, 一旦获得便可以运行。 Notifyall( )把对象wait pool中的所有线程都移入lock pool。,41,示例-Producer/Consumer,Producer线程:每隔300ms产生一个字母压栈theStack , 共200个。,Public void run( ) char c ; for(int I=0; I200; I+) c=(char)(math.random()*26+A); theStack.push( c); try Thread.sleep(300) ; catch(InterruptedException e) ,42,示例-Producer/Consumer,Consumer线程:从栈theStack中取200个字符,间隔300ms。,Public void run( ) char c ; for(int I=0; I200; I+) c = theStack.pop( ); try Thread.sleep(300) ; catch(InterruptedException e) ,43,示例-Producer/Consumer,堆栈类SyncStack: 为了保证共享数据一致性,push( ) 与pop( ) 定义成 synchronized; 为了实现Producer 与 Consumer之间的同步,加入 wait( ) 与notify( ) public class SyncStack private Vector buffer = new Vector(400,200) ; public synchronized char pop( ) ; public synchronized void push(char c) ,44,示例-Producer/Consumer,Pop( )方法: public synchronized char pop( ) char c ; while(buffer.size( ) =0) try this.wait( ); catch(InterruptedException e) c=( (Character)buffer.remover(buffer.size( )-1).charValue(); return c ; ,45,示例-Producer/Consumer,Push( )方法: public synchronized void push(char c) this.notify( ); Character charObj = new Character( c ); buffer.addElement( char Obj); ,46,不建议使用的方法, Stop( ) 线程强行终止,容易造成数据的不一致。 suspend( ) 和 resume( ) 使一个线程A可以通过调用B.suspend( )直接控制B的运行。 Suspend( )方法将不使B释放锁。容易发生死锁。建议使用 wait( )和notify( ).,47,线程状态与生命周期,Runnable,Running,Otherwise Blocked,Dead,Blocked in Objcets lock pool,Blocked inObjects wait pool,48,线程状态,几种基本状态new, Runnable, Running, Dead, Blocked等。 线程状态由线程控制方法,如sleep( ), join()或线程同步 控制方法引起变化。,49,线程分组(Grouping Threads),线程组: 每个Java线程都是归属于一个线程组。线程组机制把多个线程集合为一个对象,从而可以实现对这些线程整体操作。 线程组由java.lang中的ThreadGroup 类实现。 线程属于某个线程组具有永久性。 缺省线程组 在Java Application启动时,运行系统创建缺省的线程组,称为main 。所有未指定组的线程,均属于该组。 未指定组的线程,将属于其“父线程”所在线程组。 创建属于线程组的线程 public Thread(ThreadGroup group, Runnable runnable) ; public Thread(ThreadGroup group, String name); public Thread(ThreadGroup group, Runnable runnable, String name) ;,50,ThreadGroup 类,ThreadGroup 类的方法: Collection Management Methods:activeCount ,listCurrentThreads Methods that Operate on the Group: getMaxPriority ,getName Methods that Operate on All Threads within a Group:resume ,stop,suspend Access Restriction Methods:checkAccess,

    注意事项

    本文(996-第十三章 并发.ppt)为本站会员(本田雅阁)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开