JAVA第十章学习与复习要点.pptx

上传人:wj 文档编号:17829493 上传时间:2023-08-04 格式:PPTX 页数:35 大小:284.16KB
下载 相关 举报
JAVA第十章学习与复习要点.pptx_第1页
第1页 / 共35页
JAVA第十章学习与复习要点.pptx_第2页
第2页 / 共35页
JAVA第十章学习与复习要点.pptx_第3页
第3页 / 共35页
JAVA第十章学习与复习要点.pptx_第4页
第4页 / 共35页
JAVA第十章学习与复习要点.pptx_第5页
第5页 / 共35页
JAVA第十章学习与复习要点.pptx_第6页
第6页 / 共35页
JAVA第十章学习与复习要点.pptx_第7页
第7页 / 共35页
JAVA第十章学习与复习要点.pptx_第8页
第8页 / 共35页
JAVA第十章学习与复习要点.pptx_第9页
第9页 / 共35页
JAVA第十章学习与复习要点.pptx_第10页
第10页 / 共35页
JAVA第十章学习与复习要点.pptx_第11页
第11页 / 共35页
JAVA第十章学习与复习要点.pptx_第12页
第12页 / 共35页
JAVA第十章学习与复习要点.pptx_第13页
第13页 / 共35页
JAVA第十章学习与复习要点.pptx_第14页
第14页 / 共35页
JAVA第十章学习与复习要点.pptx_第15页
第15页 / 共35页
JAVA第十章学习与复习要点.pptx_第16页
第16页 / 共35页
JAVA第十章学习与复习要点.pptx_第17页
第17页 / 共35页
JAVA第十章学习与复习要点.pptx_第18页
第18页 / 共35页
JAVA第十章学习与复习要点.pptx_第19页
第19页 / 共35页
JAVA第十章学习与复习要点.pptx_第20页
第20页 / 共35页
亲,该文档总共35页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

JAVA第十章学习与复习要点.pptx

《JAVA第十章学习与复习要点.pptx》由会员分享,可在线阅读,更多相关《JAVA第十章学习与复习要点.pptx(35页珍藏版)》请在冰点文库上搜索。

JAVA第十章学习与复习要点.pptx

河南大学软件学院,Java编程基础,主讲:

李丽,多线程,多线程基本概念创建线程的方式线程的生命周期及控制线程的优先级及调度多线程的互斥与同步守护线程(Daemon)线程组(ThreadGroup),每个任务(Task)通常就是一个程序,每个运行中的程序就是一个进程(Process),而一个程序运行时,内部又可以包含多个顺序执行流,每个执行流就是一个线程(Thread),包含多线程的应用程序称为多线程程序。

多线程基本概念,classTestSingleThreadpublicstaticvoidmain(Stringargs)m1();publicstaticvoidm1()m2();publicstaticvoidm2()System.out.println(hello);,进程和线程,main方法,m1方法,m2方法,线程是进程的组成部分,一个进程可以拥有多个线程,一个线程必须有一个父进程。

线程可以拥有自己的堆栈,自己的局部变量,但不再拥有系统资源,它与父进程的其他线程共享该进程所拥有的全部资源。

线程的执行时抢占式的。

一个线程可以创建和撤销另一个线程。

进程和线程,Java的线程是通过Java的软件包java.lang中定义的类Thread来实现的。

当生成一个Thread类的对象之后,就产生了一个线程,通过该对象实例,可以启动线程、终止线程、或者暂时挂起线程等。

创建线程的方式,创建线程的方式,

(1)通过继承Thread类来创建并启动多线程的步骤:

定义Thread类的子类,并重写该类的run方法,该run方法的方法体就是代表了线程需要完成的任务。

因此我们经常把run方法称为线程执行体。

创建Thread子类的实例,即创建线程对象。

用线程对象的start方法来启动该线程。

(2)实现Runnable接口来创建并启动多条线程的步骤如下:

定义Runnable接口的实现类,并重写该接口的run方法,该run方法的方法体同样是该线程的线程执行体。

创建Runnable实现类的实例,并以此为实例作为Thread的Target来创建Thread对象,该Thread对象才是真正的线程对象。

创建线程的方式,classSencondThreadimplementsRunnable,SencondThreadst=newSencondThread();newThread(st);,创建Thread对象时为该Thread对象指定一个名字newThread(st,”新线程1”);,Thread和Runnable使用的区别,

(1)使用Runnable接口时,类不仅可以实现Runnable接口,还可以实现其它接口。

(2)在实现Runnable接口的类中,可以通Thread.currentThread()来获取当前线程。

(3)在继承Thread的类中,直接使用this指针来获取当前线程。

知识回顾:

1、进程与线程2、线程的创建:

实现Runnable接口、继承Thread类,线程的生命周期及控制,线程是程序内部的一个顺序控制流,它具有一个特定的生命周期。

在一个线程的生命周期中,它总处于某一种状态中。

线程的状态表示了线程正在进行的活动以及在这段时间内线程能完成的任务。

创建状态,是指使用new运算符实例化一个线程对象,但该对象还未使用start()方法启动该对象,这个阶段只是在堆内为该对象的实例变量分配了空间,但该线程对象还无法参与抢占CPU使用权。

就绪状态,实例化后的线程对象调用start()方法之后,该线程就处于了就绪状态,意味着该线程随时可以运行,它需要和其它处于就绪状态的线程通过一些算法来争夺CPU的使用权。

在某一时间片里,CPU仍只能运行一个线程即正在运行的线程。

一旦某个线程拥有了CPU的使用权,那么该线程也称为正在运行的线程。

不可运行状态:

不可运行状态包括四种情况:

睡眠状态、等待状态、挂起状态和阻塞状态。

一般来说,就绪状态和不可运行状态是可以相互切换的。

死亡状态,一旦线程对象的run()执行完毕之后,就表明该线程进入了死亡状态(Dead)。

Java虚拟机会销毁处于死亡状态的线程对象占用的系统资源。

线程的生命周期及控制,线程的生命周期及控制,创建状态(newThread)myThreadthd=newmyThread();,可运行状态(Runnable)thd.start();,不可运行状态(NotRunnable)线程处于可运行状态时,当下面四种情况发生,线程就进入不可运行状态:

调用了sleep()方法;调用了suspend()方法;为等候一个条件变量,线程调用wait()方法;输入输出流中发生线程阻塞。

线程的生命周期及控制,调用sleep()方法使线程进入睡眠状态sleep()方法可以暂停指定线程的执行,让其它线程得到运行的机会。

但调用sleep()方法会抛出InterruptedException异常,必须捕获,,sleep()方法,publicstaticvoidmain(Stringargs)for(inti=0;i10;i+)trySystem.out.println(i);Thread.sleep(1000);catch(InterruptedExceptione)e.printStackTrace();,join线程,Thread提供了让一个线程等待另一个线程完成的方法:

join()方法。

当在某个程序执行流中调用其它线程的join()方法时,调用线程将被阻塞,直到被join方法加入的join线程完成为止。

joinThread.java,线程让步:

yield,yield()方法可以让当前正在执行的线程暂停,但它不会阻塞该线程,它只是将该线程转入就绪状态。

一种完全可能的状态是:

当某个线程调用了yield方法暂停之后,线程调度器又将其调度出来重新执行。

TestYield.java,死亡状态(Dead)线程的终止一般可通过两种方法实现:

自然撤消或是被停止。

自然撤消是指从线程的run()方法正常退出;而调用线程的实例方法stop()则可以强制停止当前线程。

/线程自然撤销publicvoidrun()inti=0;while(i100)i+;System.out.println(i=+i);,/线程被强行停止myThreadthd=newMyThread();thd.start();trythd.sleep(10000);catch(InterruptedExceptione)thd.stop();,死亡状态(Dead),可以通过在其他线程中调用stop()方法来终止线程,也可以由线程自己调用stop()方法,自我终止。

如果希望线程正常终止,可采用标记来使线程中的run()方法退出。

/线程自我终止publicvoidrun()while(true)/完成线程的特定功能if(time_to_die)Thread.currentThread().stop();,死亡状态(Dead),publicclassXyzimplementsRunnableprivatebooleanflag=true;publicvoidrun()while(flag)publicvoidstopRunning()flag=false;,publicclassControlThreadprivateXyzr=newXyz();privateThreadt=newThread(r);publicvoidstartThread()t.start();publicvoidstopThread()r.stopRunning();,死亡状态(Dead),死亡状态(Dead),isAlive()方法:

可以用来判断线程目前是否正在执行中。

如果线程已被启动并且未被终止,那么isAlive()返回true,但该线程是可运行或是不可运行的,是不能作进一步的分辨。

如果返回false,则该线程是新创建或是已被终止的(同样不能作进一步的分辨)。

线程优先级,Java提供一个线程调度器来监控程序中启动后进入就绪状态的所有线程。

线程调度器按照线程的优先级决定应调度哪个线程来执行。

Thread提供了setPriority(intnewPriority)和getPriorty()方法来设置和返回指定线程的优先级,其中setPriority方法的参数可以是一个整数,范围是1-10,也可以使用Thread类的三个静态常量:

MAX_PRIORITY10MIN_PRIORITY1NORM_PRIORITY5,TestPriority.java,线程同步,当有多个线程同时访问同一资源时,会发生“错误情况”例如银行取钱问题。

例:

TestCount.java,为了解决这个问题,Java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的格式如下:

synchronized(obj);通过synchronized为对象加锁,在加锁期间其它线程无法修改该资源,当该资源修改完成,该线程释放对该资源的锁定。

解决异常方式:

解决异常方式:

使用synchronized修饰某个方法,该方法只能被当前同步线程访问,不能为其它同步线程访问。

publicsynchronizedvoiddraw(Stringname,intmoney)-,死锁,当两个线程相互等待对方释放同步监视器时就会发生死锁,Java虚拟机没有监测,也没有采用措施来处理死锁,所以编程时应该采取措施避免死锁的出现。

一旦出现死锁,整个程序既不会发生任何异常,也不会给出任何提示,只是所有线程处于阻塞状态,无法继续。

TestDeadLock.java,ProducerConsumer.java,线程同步之生产者消费者问题,为了解决所出现的问题,在Java语言中可以用wait()和notify()/notifyAll()方法(在java.lang.Object类中定义)来协调线程间的运行进度(读取)关系。

wait()方法的作用是让当前线程释放其所持有的“对象互斥锁”,进入wait队列(等待队列);而notify()/notifyAll()方法的作用是唤醒一个或所有正在等待队列中等待的线程,并将它(们)移入等待同一个“对象互斥锁”的队列。

需要指出的是:

notify()/notifyAll()方法和wait()方法都只能在被声明为synchronized的方法或代码段中调用。

线程通信,程序无法准确控制线程的轮换执行,但可以通过一些机制来保证线程协调运行。

(1)线程的协调运行可以通过Object类的wait(),notify()和notifyAll方法来协调线程运行。

(2)使用管道流可以使用管道流在两个线程之间进行更多的信息交互。

例:

PipeCommunicationTest.java,线程通信,使用管道流实现多线程通信的步骤:

(1)创建管道输入流和管道输出流

(2)使用connect方法把连个输入流和输出流连接起来。

(3)将管道输入流和输出流分别传入两个线程。

(4)两个线程分别依赖各自的管道输入和输出流进行通信。

通常没有必要使用管道流来控制两个线程之间的通信,因为两个线程属于一个进程,它们可以非常方便地共享数据,这种方式才是线程之间通信的最好方式,而不是管道流。

说明:

守护线程(Daemon),在客户/服务器模式下,服务器的作用是持续等待用户发来请求,并按请求完成客户的工作。

守护线程是为其它线程提供服务的线程,它一般应该是一个独立的线程,它的run()方法是一个无限循环。

可以用方法publicbooleanisDaemon()确定一个线程是否守护线程,也可以用方法publicvoidsetDaemon(boolean)来设定一个线程为守护线程。

守护线程与其它线程的区别是,如果守护线程是唯一运行着的线程,程序会自动退出。

一般当最后一个线程结束时,Java程序才退出守护线程的存在不影响Java程序的退出setDaemon(true)使线程成为守护线程(必须在start之前调用)setDaemon(false)使线程成为一般线程(必须在start之前调用)守护线程一般不能用于执行关键任务任务未执行完,线程就可能被强制结束守护线程一般用来做辅助性工作提示,帮助等,守护线程(Daemon),Java使用ThreadGroup来表示线程组,它可以对一批线程进行分类管理,Java允许程序对线程组进行控制。

对线程组的控制相当于同时控制这批线程。

用户创建的所有线程都属于指定线程组,如果程序没有显式指定线程属于哪个线程组,则该线程属于默认线程组。

在默认情况下,子线程和创建它的父线程处于同一个线程组内。

一旦某个线程加入了指定线程组之后,该线程将一直属于该线程组,直到该线程死亡,线程运行过程中不能改变它所属的线程组。

线程组,构造方法ThreadGroup(StringgroupName)ThreadGroup(ThreadGrouptg,StringgroupName)声明线程的线程组缺省创建的线程与父线程同组Thread(ThreadGrouptg,Runnablero)Thread(ThreadGrouptg,Runnablero,StringthreadName),线程组,intactiveCount()线程组下的所有活动线程数getMaxProirity/setmaxProirity获得/设置线程组中线程的最大优先级getName获得线程组的名字iterrupt():

中断该线程组内的所有线程。

isDaemon():

判断该线程组是否是后台线程组。

setDaemon():

把该线程组设置成后台线程组。

ThreadGroup还提供了如下方法:

例:

ThreadGroupTest.java,

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 哲学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2