Java语言多线程编程.ppt_第1页
Java语言多线程编程.ppt_第2页
Java语言多线程编程.ppt_第3页
Java语言多线程编程.ppt_第4页
Java语言多线程编程.ppt_第5页
已阅读5页,还剩39页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第八章Java语言多线程编程 一 线程的概念二 线程的实现方法三 线程的同步与死锁四 多线程程序实例 一 线程的概念 进程与线程进程是指可执行程序并存放在计算机存储器空间的一个指令序列 它是一个动态执行的过程 进程是计算机多任务操作系统为任务分配资源的最小单位 每个进程都应该有自己的内存空间 线程同进程一样 也是一个动态的概念和一个动态的执行过程 但是线程比进程的内涵要小一个等级 一般一个进程 应用程序 包含一个或多个线程 线程需要在进程的内存地址空间中运行 是多任务操作系统用于分配计算机CPU时间片的最小单位 一 线程的概念 一个Java多线程程序在Java虚拟机中执行时 每一个线程的执行过程是由Java执行系统的线程调度来控制的 Java语言多线程程序自身是不能控制每个线程执行顺序的 在目前的多任务操作系统中 当一个单一线程被启动以后 它可以被挂起来 被挂起的线程程序代码并不从计算机内存中清除 只是暂时不让它执行了 在内存中被挂起的线程还可以重新被恢复执行 以便保证实现多任务被同时处理 多任务操作系统在任何时间都可以停止或终止线程 被终止的线程程序代码将被从计算机内存中清除 被终止的线程是不能再重新恢复执行的 一 线程的概念 线程调度与优先级在CPU上以某种次序执行多个线程称为调度 调度使JVM对运行的多个线程进行协调 以避免多个线程争用有限的系统资源而导致系统死机或崩溃 为控制线程的协调运行 Java定义了线程监视器来监控系统中处于就绪状态的所有线程 线程调度采用 抢占式 策略 按照线程的优先级别选择线程获得处理器 线程优先级 Priority 告诉线程监视器该线程的重要性 如果有大量线程被堵塞并等候运行时 线程监视器按线程的优先级别对线程排队 一旦空闲 线程监视器会首先选择运行具有最高优先级的那个线程 当然这并不表示优先级别较低的线程不会运行 即线程不会因为存在优先级而导致死锁 一 线程的概念 Java将线程的优先级分为10个等级 分别用1 10之间的数字表示 数字越大表明线程的优先级别越高 Thread类中定义了代表线程优先级的三个静态整型数据成员MIN PRIORITY MAX PRIORITY和NORMAL PRIORITY 分别对应于线程的最高优先级 10 最低优先级 1 和普通线程优先级 5 当创建一个线程对象时 其默认的优先级别是5 一个线程的优先级别可以通过调用Thread类中的getPriority 方法来获得 而通过调用setPriority 方法可以改变一个线程的优先级别 一 线程的概念 线程的状态与生命周期每个线程都与生命周期相关联 一个生命周期含有多个可以互相转换的状态 线程从产生到消亡的生命周期中要经历创建 就绪 运行 阻塞和死亡五种状态 通过线程的控制与调度可使线程在这几个状态间转换 每个Java程序中都拥有一个与main方法对应的主线程 必须在主线程中创建新的线程 1 创建状态 当一个Thread类或其子类的对象被声明并创建后 该线程对象就处于创建状态 创建状态是线程已经创建但未开始执行的一个特殊状态 处于创建状态的线程只是一个空的线程对象 系统不为它分配资源但有自己的内存空间 通过调用start 方法进入就绪状态 一 线程的概念 2 就绪状态 处于就绪状态的线程已经具备运行条件但还未获得时间片 因此进入线程队列 等待系统为其分配CPU 一旦获得CPU 该线程便进入运行状态并自动调用自己的Run 方法 3 运行状态 当就绪状态的线程被调度并获得处理器资源时便进入运行状态 这时开始执行run 方法中的代码 直到调用其他方法而终止 或等待某资源而阻塞 或运行完毕而死亡 4 堵塞状态 处于运行状态的线程在某些情况下 如执行睡眠方法或等待I O设备操作时 将让出CPU并暂时终止自己的运行进入阻塞状态 阻塞时线程不能进入就绪队列 只有当引起阻塞的原因消除时 线程才可以转入就绪状态 重新进入线程队列等待调度 5 死亡状态 死亡状态是线程生命周期的最后一个阶段 表示线程已经退出运行状态并且不再进入就绪队列 当线程的run 方法结束或由于其它原因被终止后 线程便进入消亡状态 线程的终止分为两种形式 一是自然死亡即线程的run 方法正常结束 二是强制终止线程 如调用destory 或stop 命令终止线程 一 线程的概念 一个线程的生命周期分为生成 运行 等待 终止等阶段 各阶段及状态间的转换条件具体如图所示 一 线程的概念 说明 控制一个线程生命周期最常用的方法有start 方法 启动一个线程 run 方法 定义线程动作 sleep 方法 使线程睡眠一段时间 suspend 方法 使线程挂起 resume 方法 恢复挂起的线程 yield 方法 把线程移到队列的尾部 stop 方法 结束线程生命周期并执行清理工作 destroy 方法 结束线程生命周期但不做清理工作 wait 方法 使一个线程进入等待状态 notify 方法 将等待线程激活 一 线程的概念 1 start 线程调用该方法启动一个线程 使之从新建状态进入就绪队列 一旦获得CPU就可以脱离创建它的主线程独立开始自己的生命周期 2 run 线程的所有活动都是通过线程体run 方法定义 并实现线程对象被调用之后所执行的操作 3 stop 为强制终止某个线程的执行 Thread类提供了线程最后一个控制即停止方法stop 4 suspend 在Java语言程序中经常需要挂起一个线程而不指定多少时间 此时可用Thread类提供的suspend 方法 这个方法并不永久地停止线程 5 resume 暂停的线程可以重新激活 重新激活的方法为resume 方法 由于suspend 包含了对象锁 所以它使线程极易出现死锁现象 即被锁住的对象在永久地等待resume 方法 对暂停的线程不能使用start 方法重新启动该线程 6 isAlive 一个线程已经启动而且没有停止则被认为是激活的 可通过测试线程来判断线程是否被激活 测试方法为isAlive 如果isAlive 方法返回true 则该线程是激活的 一 线程的概念 7 sleep Java语言Thread类中提供的sleep 方法是简单地告诉线程休息多少个毫秒的时间 如果想要推迟一个线程的执行 则可以使用sleep 方法 当线程睡眠的时候 sleep 方法并不占用系统资源 其他的线程仍然可以继续工作 一旦延迟时间完毕 则该休眠线程就被激活 sleep 方法的基本调用形式采用一个以毫秒为单位的参数 它使线程暂停一段规定的延时时间 当延时完成后 线程则继续工作 由于Java运行系统采用了线程调度机制 所以通过在run 的主循环中插入对sleep 的调用 一般都可以使Java语言程序运行得更快一些 因为在正在运行的线程准备进入休眠状态之前 较短的延迟可能造成sleep 结束调度机制的中断 强迫调度机制将其中止 并于稍后重新启动 以便该线程能做完它自己的事情 再进入休眠状态 8 wait 和notify 当编写的Java语言程序被分成几个逻辑线程时 需要清晰地知道这些线程之间应怎样相互通讯 例如网络数据交换程序经常需要使用Sleep Wait Suspend 等方法使一个线程进入等待状态 同时需要另一个线程使用Notify Resume 等方法将等待线程激活 一 线程的概念 Java语言在0bject类中提供了wait 等待和notify 通知方法 其功能是用来使线程之间相互协调 当编写程序处理某些特定事件时 它需要等候某些其他条件 从线程外部加以控制的 相当于外部触发信号 发生变化后来决定事件处理方法 但是同时又不想在自己线程内部一直等待下去 解决处理特定事件的最好方案之一便是使用wait 和notify 方法同时配合检查条件是否满足 在Object类中wait 和notify 的定义为 publicclassjava lang 0bject publicfinalvoidnotify 通知方法publicfinalvoidnotifyAll 通知所有的等待publicfinalvoidwait 等待方法publicfinalvoidwait longtimeout publicfinalvoidwait longtimeout intnanos 一 线程的概念 说明 wait 和notify 方法都属于基础类Object的一部分 不像sleep suspend 以及resume 那样属于Thread类的一部分 wait 等待方法可以使一个线程所在的某一个对象的synchronized方法进入等待状态 直到其他线程通过notify 通知方法将它唤醒 而且只有在一个notify 方法发生变化的时候 线程才会被唤醒 在Java语言中 也可以有多个线程同时进入等待状态并等待同一个唤醒消息notifyAll 将它们唤醒 wait 方法允许将线程置入睡眠状态 而同时又积极地等待条件的发生来改变睡眠状态 由此可见 wait 和notify 方法提供了在线程之间进行有效同步的一种手段 wait 和sleep 的区别在于wait 方法在执行期解除对象的锁 而且能够自由地退出wait 方法 因为一个notify 方法便可以强行迫使延迟时间迅速流逝 第二种基本形式为不采用任何参数 它意味着wait 方法会持续执行 不会自行结束 直到其他线程notify 方法的介入为止 一 线程的概念 wait 和notify 方法是与对象的锁相关联的 即这两个方法操纵对象的锁 在Java语言程序中 无论使用sleep 方法还是suspend 方法 都不会在自己被调用的时候解除对它们所在对象的锁定 但是在线程对象的synchronized方法中调用wait 方法进入等待状态时 却可以解除它所在对象的锁 这就意味着在执行wait 方法期间可以调用线程对象中的其他同步方法 可以将一个wait 方法置入任何同步方法内部 无论在类中是否准备进行涉及线程的处理 事实上 能调用wait 方法的惟一地方是在一个同步的方法或代码块内部 若在一个不同步的方法内调用wait 或者notify 方法 Java语言程序会通过编译 但是在运行程序时 就会出现一个非法监视器状态异常 lllegalMonitorStateException 二 线程的实现方法 线程类ThreadThread类是在Java语言中实现多线程时最常用的类 在Thread类中封装了线程的各种属性和方法 Thread类的成员包括了最常用的启动start 执行run 终止stop 暂停suspend 线程以及设置线程优先级 实现线程之间通信等各种方法 Thread类实现了在Java语言的java lang Runnable包中定义的Runnable接口 这个接口只定义了一个公共的run 方法 run 方法是线程的核心 在run 方法里给新产生的进程分配任务 任何实现Runnable接口的类都须实现run 方法 一般在线程类的run 方法中放置线程的主处理逻辑 二 线程的实现方法 Runnable接口定义为 publicinterfacejava lang Runnable publicabstractvoidrun Thread类的start 方法用于开始线程的执行 调用start 方法将导致run 方法的执行 除此之外start 方法不做任何事情 当线程进入run 方法后便可执行里面的任何程序 一旦run 方法中的程序代码被执行完毕 则意味着这个线程的自动结束 run 方法是线程执行的主体 在Java语言应用程序中main 方法是应用程序的执行起点 对于线程而言run 方法就是线程的执行起点 线程默认的run 方法是不做任何事情的 需要通过重载run 方法来完成线程任务 二 线程的实现方法 继承Thread定义一个Thread类的子类 在子类的run 方法中放置自己的处理过程 然后在主程序中创建这个类的实例 使用start 方法开始线程的执行 例如 classmyThreadextendsThread publicvoidrun 定义自己的处理过程 myThread newThread 创建线程myThread start 启动线程 二 线程的实现方法 例 通过继承Thread类实现多线程publicclassTwoThread publicstaticvoidmain Stringargs DelayOutputThreadthreadl thread2 threadl newDelayOutputThread 创建2个线程对象thread2 newDelayOutputThread threadl start 开始启动2个线程thread2 start try Thread sleep 10000 catch InterruptedExceptione System out println threadhaswrong 二 线程的实现方法 classDelayOutputThreadextendsThread privatestaticintthreadCount 0 privateintthreadNumber 0 privateintdelay publicDelayOutputThread delay int Math random 5000 threadCount threadNumber threadCount publicvoidrun try sleep delay catch InterruptedExceptione System out println Thread threadNumber withadelayOf delay 二 线程的实现方法 实现Runnable接口当需要构造一个继承类 而且想使该类具有线程处理能力时 使用定义一个实现Runnable接口的类是最合适的 当定义了实现Runnable接口的类后 它并没有获得与线程配套提供的所有功能 所以还需要创建一个新的线程对象 使继承类具备线程功能 该操作将定义的继承类作为一个对象参数传递给Thread对象的构造方法来创建线程对象 然后才可以通过调用Thread类中的start 方法开始线程的执行 在Java程序中 可以在任意实现的接口对象上启动一个线程 而接口是一个抽象接口 它用来表示本对象有一个方法想要异步执行 通过在继承类中重构Runnable接口中的run 方法 放置主处理过程模块来完成该线程的任务 二 线程的实现方法 classmyclassimplementsRunnable publicvoidrun 定义该类完成的功能 myclassmyobj newmyclass 创建类的实例ThreadmyThread newThread myobj 类作为参数传递哈Thread对象MyThread start 调用start 方法开始线程的执行说明 通过使用Thread类 Java语言程序可以创建多个对象来执行相互独立的任务 如果一个线程创建了新的线程 那么它创建的线程就是它的子线程 而它就被称为父线程 每个进程有一个主线程 当主线程结束时 其他子线程也被终止 通过继承Thread类或实现Runnable接口声明的类都需要重新构造run 方法 在每个独立类中封装各自的run 方法 编写每个线程完成的独立任务 从而实现多线程程序 在创建每一个线程时 应该通过setName 方法给每个线程一个名字 以便提供该线程名字的输出和方便多线程程序的调试 二 线程的实现方法 例 定义实现Runnable接口实现多线程classTwoThreadimplementsRunnable TwoThread ThreadThreadl Thread currentThread Threadl setName Thefirstmainthread System out println Therunningthread Threadl Threadthread2 newThread this thesecondthread System out println creatanotherthread thread2 start publicvoidrun try for inti 0 i 5 i System out println Sleeptimeforthread i Thread sleep 1000 catch InterruptedExceptione System out println threadhaswrong publicstaticvoidmain Stringargs newTwoThread 二 线程的实现方法 多线程在Applet中的应用设计Applet小程序是为了给Web页增加交互性 使Web页面更加生动活泼 因此那些真正有用的Applet小程序 如动画 实时更新Internet服务器信息回取 一般娱乐等通常都是持续运行的 即Applet小程序的逻辑主体存在着无限循环情况 这个逻辑主体不宜放在几个浏览器调用方法中 因为在隐含的情况下 Applet小程序所有主逻辑都采用单一线程 当浏览器调用的方法中出现了死循环时 则程序控制将不被返回 如果用户换到另一个页面之后小程序仍还在运行 这样就会浪费处理器资源 不使这种情况发生的方法就是在Applet小程序框架中加入线程 把逻辑主体放在线程run 方法中 只在浏览器调用start 方法中生成线程 而在stop 方法中终止线程运行 这样就不会浪费处理器资源了 二 线程的实现方法 www浏览器 Applet小程序 多线程程序是所有浏览器采用的模型 Java applet Applet类本身并不支持线程 因此在实际使用中为方便操作 可以派生Applet类生成一个支持线程的子类 再来编写Applet小程序时 就可以直接从子类中派生 程序逻辑主体放在run 方法中 将线程控制隐藏起来 支持多线程Applet小程序的定义为 importjava applet importjava awt classMultiThreadAppletextendsAppletimplementsRunnable ThreadthisThread publicvoidstart if thisThread null thisThread newThread this thisThread start publicvoidstop if thisThread null thisThread stop thisThread null publicvoidrun 二 线程的实现方法 例 无限循环累加器多线程Appletimportjava awt publicclasscounterextendsMultiThreadApplet intCounter publicvoidrun while true Counter Repaint publicvoidpaint Graphicsg g drawString String valueOf Counter 20 20 说明 实例8 3中Applet小程序继承了MultiThreadApplet类 所以它对线程的操作已被隐藏在MultiThreadApplet中 该程序功能包含一个无限循环累加操作 并将结果显示在屏幕上 在run 方法中的repaint 方法的执行过程是 系统首先调用的是update 方法将整个窗口重新刷新一次 然后再调用paint 方法在窗口里画出要显示的内容 三 线程的同步与死锁 同步的概念Java语言创建和控制线程都是很容易的 多线程的一个重要特点就是线程之间可以互相通讯 可以设计线程使用公用对象 使每个线程都可以独立操作公用对象 但是在多线程之间存在着诸如线程之间协调地共享资源 避免线程死锁 协调相互依赖的问题 因为一个程序可以创建许多线程 所以多线程共享相同的资源的情况并不少见 在同一时间里两个或多个线程访问共享的资源将产生并发问题 结果可能导致变量数据更新的丢失 或者是访问变量时返回不正确的值等错误 三 线程的同步与死锁 如果想要两个线程通讯并共享 个复杂的数据结构 则需要一种机制让它们相互牵制并且正确执行 为这个目的 Java语言用一种叫监视器 monitor 的机制实现了线程间的异步执行 可以将监视器看作是一个很小的盒子 它只能容纳一个线程 一旦一个线程进入一个监视器 所有其他线程必须等到第 个线程退出监视器后才能进入 监视器可以设计成保护共享的数据不被多个线程同时操作 Java语言提供了一种更清晰的解决方案 采用将每个对象的成员方法定义成synchronized来实现自己的监视器 一旦线程在一个synchronized方法里执行时 其他任何线程都不能在此时刻调用同一个对象的synchronized方法 又因为多线程提供了程序的异步执行功能 所以在多线程编程中还有必要提供一种线程同步机制 三 线程的同步与死锁 一个执行synchronized方法的线程是可以判断出自己是否无法再继续执行该方法 因此它可以自愿地调用wait 方法进行等待 这样可以使该线程不再争用处理器和监视器对象 而是在线程队列中进行等待 当一个执行synchronized方法的线程结束时 该对象会调用notify 方法通知某个等待的线程 并使它变为就绪状态 这样它就可以获得该监视器对象的开锁钥匙并开始执行 这里的notify 方法就像是发给等待线程的一个信号 告诉该线程它所等待的条件现在已满足了 因此有资格重新进入监视器 如果一个线程调用notifyAll 方法 那么所有正在等待该对象的线程就都有资格重进入监视器 也就是说 它们都被设置为就绪状态 特别注意的是 在这些线程中 一次只能有一个线程获得该对象的开锁钥匙 三 线程的同步与死锁 Java语言的监视器实际上是完成线程调度工作的 它是将所有等待进入监视器执行synchronized方法的线程进行排队 如果一个线程要调用某个对象的一个synchronized方法 而此时另一个线程已经在执行该对象的synchronized方法了 那么该线程将进入队列等待执行 如果一个线程在对象中进行操作时调用了wait 方法 那么该线程也要进入队列 把由于监视器忙而阻塞的等待线程与由于在监视器中显式地调用wait 方法而等待的线程区分开是很重要的 当一个synchronized方法执行完后 由于监视器忙而阻塞的外部线程就可以执行 而那些显式地调用了wait 方法的线程则只能在其他线程用notify 或notifyAll 方法将其唤醒时才能继续执行 当一个进入队列的线程具有了继续执行的资格时 调度程序就选择优先级最高的线程来执行 三 线程的同步与死锁 Synchronized方法关键字synchronized是用来作为指定安全线程的修饰符 而且可以作为一个语句来指定代码的临界段 当作为方法的修饰符使用时 synchronized指出该方法应该在同 时间只对 个线程有效 当声明程序中所有线程的run 方法为synchronized时 可以保证线程的异步顺序执行 在Java语言程序中 为使线程处于同步工作状态 每个对象都配备了 个与之相关联的锁 在调用对象中的任何synchronized方法时 该对象就会被锁定 当一个对象被locked 锁住 的时候 任何试图访问该对象中的变量或调用对象中的其他任何synchronized方法的操作都需要等待锁被打开方可进行 当对象中被调用的synchronized方法完成了自己的工作后 则该对象被自动解除锁定 三 线程的同步与死锁 对于一个多线程程序 虽然把一个方法声明成synchronized是一种解决并发访问问题的很简单的途径 但是因为每个线程都必须等待执行线程的同步方法结束直到轮到自己 所以这对程序的性能会造成不良的影响 对于耗时很长才能结束的复杂synchronized方法 该程序的性能损失是非常之大的 为了降低对整个方法进行synchronized声明时它对程序性能所造成的影响 可以使用同步synchronized语句来代替同步方法 当程序块执行到方法中访问共享对象的时候 synchronized语句才锁定该对象 因此 在这种方式下 synchronized方法在整个执行过程中对象的锁并不总是保持有效 只有在synchronized语句被执行时对象的锁才有效 这样程序的效率有可能会更高一些 三 线程的同步与死锁 线程死锁当一个线程在执行过程中由于某种原因而暂时阻止了该线程的执行 则该线程处于堵塞状态 被堵塞的线程在没有外界干扰的情况下有可能永远不会被执行 由于线程可能进入堵塞状态 而且由于对象中可能会拥有同步方法 除非同步锁定被解除 所以一个线程完全有可能等候另一个对象 而另一个对象又在等候下一个对象 依此类推 该等候链最可怕的情形就是进入封闭的循环等候状态 此时所有线程都会陷入无休止的相互等待状态 谁也动弹不得 如果对于一个要加锁的对象永远不能被锁 那么等着给它上锁的线程将无限期地等待 这种情况称为死锁 当两个或多个线程因为等待已被其他线程占有的锁而被永久地冻结时便发生了死锁 三 线程的同步与死锁 造成线程被堵塞可能是有以下几个方面的原因 1 调用sleep 方法 使线程进入睡眠状态 在规定的时间内 这个线程是不会运行的 2 用suspend 方法暂停了线程的执行 除非线程收到resume 方法消息 否则不会返回就绪状态 3 用wait 方法暂停了线程的执行 除非线程收到nofify 或者notifyAll 消息 否则不会变成就绪状态 4 线程正在等候一些I 0 输入输出 操作的完成 即若 个数据流需要等候一些I 0活动时 它便会自动进入堵塞状态 5 线程试图调用另一个对象的同步方法 但那个对象正处于锁定状态 即在调用对象的synchronized方法时 该对象的另一个synchronized方法正在执行 6 调用yield 方法自动放弃CPU 以便其他线程能够运行 三 线程的同步与死锁 采用适当的防备措施 可以大大降低死锁发生的可能性 1 避免从另一个synchronized方法或代码块中调用一个synchronized方法 如果需要嵌套synchronized方法的话 总是按照相同的顺序调用它们 2 在设计类时 尽量减少对共享资源的访问 3 创建多线程程序中出现一个线程需要等待直到另一线程改变了一个对象或变量的状态情况时 可以使用一种简单的线程协同 可以人为地协调 技术来处理这些情况 四 多线程程序实例 例 模拟银行帐户的操作packageObjbalances123 importjava lang importjava awt importjava util classObjBalancesextendsFrame Labelnames TextFieldsbalances Buttonstart stop exit intsum 0 Customercustomers Tellerteller1 teller2 teller3 publicObjBalances super 银行平衡表 setLayout newBorderLayout setBackground Color lightGray Panelp1 newPanel Panelp2 newPanel add South p2 add Center p1 p1 setLayout newGridLayout 6 2 sbalances newTextField 6 names newLabel 6 names 0 newLabel zhangsan names 1 newLabel lisi names 2 newLabel wangwu names 3 newLabel zhaoliu names 4 newLabel houqi names 5 newLabel zhongji customers newCustomer 5 for inti 0 i 5 i customers i newCustomer 1000 intb customers i getBalance sum b sbalances i newTextField newInteger b toString Panelp newPanel p1 add p p1 add names i p1 add sbalances i p1 add p 四 多线程程序实例 sbalances 5 newTextField newFloat sum toString Panelp newPanel p1 add names 5 p1 add p p add sbalances 5 start newButton start stop newButton stop exit newButton exit p2 add start p2 add stop p2 add exit reshape 100 100 300 250 show publicvoidpaint Graphicsg floatsum 0 for inti 0 i 5 i intb customers i getBalance sbalances i setText newInteger b toString sum b sbalances 5 setText newFloat sum toString publicvoidclickStart teller1 newTeller customers 5 1 teller2 newTeller customers 5 5 teller3 newTeller customers 5 7 teller1 start teller2 start teller3 start start disable 四 多线程程序实例 publicvoidclickStop teller1 stopit teller2 stopit teller3 stopit start enable repaint publicbooleanaction Eventevt Objectarg if evt target start clickStart returntrue elseif evt target stop clickStop returntrue elseif evt target exit System exit 0 returntrue elsereturnsuper action evt arg publicstaticvoidmain Stringargv newObjBalances classCustomer intbalance publicCustomer intmoney balance money publicvoidchangedLedger intvalue balance value publicintgetBalance returnbalance classTellerextendsThread intcount amount Customercust Booleanstop flag publicTeller Customercst intcnt intamt count cnt amount amt cust cst stop flag false publicvoidstopit stop flag true 四 多线程程序实例 publicvoidrun Customercustf custto while true intfrom int Math round Math random count 1 intto int Math round Math random count 1 if from to custf Customer cust from custto Customer cust to synchronized custf custf changedLedger amount synchronized custto custto changedLedger amount if stop flag stop 四 多线程程序实例 例 交通路口车辆通过这是一个比较复杂的包含动画线程的Applet小程序 它是一个非协同多线程动画模拟车辆通过交通路口的程序 在程序中使用由0bject类提供的wait 和notify 方法来协同线程 wait 方法的调用将导致线程释放它的锁 调用wait 的线程将被挂起直到另一个线程通过notify 或notifyAll 方法的调用通知它 处于等待的线程随后将被唤醒 并试图重新获得对象锁的所有权 如果因为对象的状态的原因而使线程不能完成其功能的话 它可用再次调用wait 方法 这个过程将被一直重复直到线程能完成它的任务 四 多线程程序实例 importjava applet Applet importjava awt publicclassOrderlyIntersectionextendsAppletimplementsRunnable ThreadAnimThread null IcarLrcar Tbcar TrafficCoptCop publicvoidinit resize 400 400 tCop newTrafficCop Lrcar newIcar tCop Icar leftToRight 16 Tbcar newIcar tCop Icar topToButtom 17 publicvoidstart if AnimThread null AnimThread newThread this AnimThread start if Lrcar null 四 多线程程序实例 publicvoidupdate Graphicsg if isValid paint g return Lrcar updateCar g Tbcar updateCar g classIcarextendsThread publicintlastPos 1 publicintcarPos 0 publicintspeed 10 publicintdirection 1 publicTrafficCoptCop publicfinalstaticintleftToRight 1 publicf

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论