配色: 字号:
Java语言程序设计基础课件ppt第11章 多线程-2
2022-08-19 | 阅:  转:  |  分享 
  
第11章多线程本章学习目标理解多线程的概念掌握如何创建线程掌握如何使线程同步理解线程优先级、状态和线程调度本节主要内容线程同
步线程优先级线程调度线程间的通信线程同步当多个线程对同一资源访问时可能会引起冲突。示例:DepositInBan
k.java通过线程同步解决对共享资源访问的问题。示例:DepositInBankWithSync.java线程同步将方
法同步的格式如下:synchronized返回值类型方法名(){}一个简单的应用例子如下:
publicclasssomeClass { publicsynchronizedvoidaMeth
od() { //Synchronizedcodeblock } }线程同步将某方法
中某段代码同步的语法如下: synchronized(对象)
{需要同步分代码段;}一个简单的应用例子如下: publicclass
someClass{ publicvoidaMethod(){ ... syn
chronized(this) { //Synchronizedcodeblock } ..
. } }线程的优先级线程可以设定优先级,高优先级的线程可以安排在低优先级线程之前完成。Java中
,线程的优先级从低到高以整数1~10表示,共分为10级。设置优先级是通过调用线程对象的setPriority()方法来进行的。
默认优先级为5,优先级高的线程获得CPU时间的机会相对较高。示例:ThreadPriority.java线程的调度publi
cstaticvoidsleep(longmillis)throwsInterruptedException使当前运
行的线程休眠millis指定的毫秒数。publicstaticvoidyield()当前正在运行的线程让出CPU,允许其
它线程运行。publicfinalvoidwait()throwsInterruptedException使当前线程
处于等待状态,直到其它线程唤醒它。publicfinalvoidnotify()唤醒一个正在等待的线程。public
finalvoidnotifyAll()唤醒所有正在等待的线程。线程的状态new(新建):一个线程在调用new()方
法之后,调用start()方法之前所处的状态。runnable(就绪):一旦线程调用了start()方法,线程就转到Runnab
le()状态。注意,如果线程处于Runnable状态,它也有可能不在运行,这是因为还存在优先级和调度问题。running(运行状
态):线程正在占用CPU时间blocked(阻塞/挂起状态):线程处于阻塞状态。这是由两种可能性造成的:因挂起而暂停;由于某些原
因而阻塞,例如等待IO请求的完成等。dead(终止状态):线程转到退出状态。这有两种可能性:run()方法执行结束;调用了sto
p()方法。线程状态之间的切换线程控制(线程调度)sleep()方法是使线程停止一段时间的方法。在sleep时间间隔
期满后,线程不一定立即恢复执行。这是因为在那个时刻,其他线程可能正在运行而且没有被调度为放弃执行,除非:(a)“醒来”的
线程具有更高的优先级;(b)正在运行的线程因为其他原因而阻塞。来看如下程序段: publicclassTest
implementsRunnable{ publicvoidrun(){ while(true){
try{Thread.sleep(10);
}catch(InterruptedExceptione){
//Thisthread''ssleepwasinterrupted
//byanotherthread}
}}}线程控制(线程调度)Thread类的sleep()方法对当前线程操作
,它是一个静态方法。sleep()的参数指定以毫秒为单位的线程最小休眠时间,除非线程因为中断而提早恢复执行,否则它不会在这段时间之
前恢复执行。线程控制(线程调度)Thread类的另一个静态方法yield(),可以用来使具有相同优先级的线程获得执行的机会。
如果具有相同优先级的其他线程是可运行的,yield()将把调用线程放到可运行池中并使另一个线程运行。如果没有相同优先级的可运行进程
,yield()什么都不做。sleep()调用会给较低优先级线程一个运行的机会。yield()方法只会给相同优先级线程一个执行的
机会。线程控制(线程调度)示例:无协同的生产者/消费者ProducerConsumer1.java示例:使用yield进
行协同ProducerConsumer2.java注意:如果没有相同优先级的可运行进程,yield()什么都不做。线程控制(
线程调度)java.lang.Object类中提供的两个用于线程调度的方法:wait()和notify()。在进行线程同步时,
可以使用wait()/notify()方法进行线程的协同。如果线程对一个同步对象x发出一个wait()调用,则该线程会暂停执行
,释放锁标记,进入阻塞状态。线程控制(线程调度)如果对一个同步对象x发出一个notify()调用,则从阻塞状态的线程中唤醒
一个线程去等待该对象的锁标记,一旦获得锁标记,便从上一次wait()处接着运行。notifyAll()方法唤醒所有因一个同步对象
调用wait()阻塞的所有线程。示例:ProducerConsumer3.java注意:wait()/notify()必须在同
步块中由同步对象调用。线程之间的通信Java语言提供了各种各样的输入/输出流,使我们能够很方便地对数据进行操作。其中,
管道(Pipe)流是一种特殊的流,用于在不同线程间直接传送数据(一个线程发送数据到输出管道,另一个线程从输入管道中读数据)。通过使
用管道,就可实现不同线程间的通信,无需求助于类似临时文件之类的东西。线程之间的通信PipedInputStream代表了线程
从管道读数据的一端;PipedOutputStream代表了线程向管道写数据的一端这两个类一起使用可以提供数据的管道流。
为了创建一个管道流,我们必须首先创建一个PipedOutStream对象,然后创建PipedInputStream对象。线程之
间的通信示例:PipeTest.java上面的例子拥有一个产生随机数的生产者线程;一个在屏幕上输出结果的消费者线程。这个程序不会自动结束,用户可以通过Ctrl+C键来终止它。综合练习编写下图所示的应用程序,通过多线程实现球移动的动画:点击"Start"按钮,则从左上角生成一个球在界面移动并反弹;点击"Close"按钮则退出程序。BallGame.java总结创建线程的两种方法线程同步线程调度线程通信
献花(0)
+1
(本文系在羡智库原创)