《java语言程序设计-课件.ppt》由会员分享,可在线阅读,更多相关《java语言程序设计-课件.ppt(41页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、Java语言程序设计语言程序设计多线程程序设计多线程程序设计多线程程序设计1线程概述线程概述2编写线程程序编写线程程序345线程的生命周期线程的生命周期多线程的同步处理多线程的同步处理(重点重点)多线程的同步问题多线程的同步问题(难点难点)C C最新发展最新发展1989年,C语言被 ANSI 标准化(ANSI X3.159-1989)1990年,ISO ANSI ISO1999年,ISO 9899:1999的发表。它通常被称为C992011年12月8日,ISO正式发布了新的C语言的新标准C11,官方名称为ISO/IEC 9899:2011。支持多线程1969年到1973年之间,为了在PDP-1
2、1电脑上运行的UNIX系统所设计出来的编程语言。1973年,Unix操作系统的核心正式用C语言改写,这是C语言第一次应用在操作系统的核心编写上。肯汤普逊和丹尼斯里奇C+C+最新发展最新发展2011-09-11发布支持多线程是C+语言最大的变化之一。此前,C+只能利用操作系统的功能(Unix族系统使用pthreads库),或是例如OpenMP和MPI这些代码库,来实现多核计算的目标。C+11语法,建议阅读Professional C+,或C+Primer Plus。C+11多线程主题方面,建议阅读C+Concurrency in Action。一、线程概述一、线程概述程序程序是一组是一组指令指令
3、的有序集合。的有序集合。进程进程是一个具有一定独立功能的程序在一个数据集合上是一个具有一定独立功能的程序在一个数据集合上的的一次动态执行过程一次动态执行过程。进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,比如在Windows 系统中,一个运行的exe 就是一个进程。进程是进程是系统系统进行资源分配和进行资源分配和调度的一个独立单位调度的一个独立单位。线程线程(threadthread)是指进程内部一段可独立执行的、有独)是指进程内部一段可独立执行的、有独立控制流的指令序列,立控制流的指令序列,进程中的多个线程共享进程的内存,是是CPUCPU调度和分派的基本单位调度和分派
4、的基本单位。一个一个程序程序至少有一个至少有一个进程进程,一个一个进程进程至少有一个至少有一个线程线程;进程和程序并不是一一对应的,一个程序执行在不同的进程和程序并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程数据集上就成为不同的进程。“同时”执行是人的感觉,在线程之间实际上轮换执行。一、线程概述一、线程概述程序程序是一组是一组指令指令的有序集合。的有序集合。进程进程是一个具有一定独立功能的程序在一个数据集合上是一个具有一定独立功能的程序在一个数据集合上的的一次动态执行过程一次动态执行过程。进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,比如在Windows
5、 系统中,一个运行的exe 就是一个进程。进程是进程是系统系统进行资源分配和进行资源分配和调度的一个独立单位调度的一个独立单位。线程线程(threadthread)是指进程内部一段可独立执行的、有独)是指进程内部一段可独立执行的、有独立控制流的指令序列,立控制流的指令序列,进程中的多个线程共享进程的内存,是是CPUCPU调度和分派的基本单位调度和分派的基本单位。一个一个程序程序至少有一个至少有一个进程进程,一个一个进程进程至少有一个至少有一个线程线程;进程和程序并不是一一对应的,一个程序执行在不同的进程和程序并不是一一对应的,一个程序执行在不同的数据集上就成为不同的进程数据集上就成为不同的进程
6、。“同时”执行是人的感觉,在线程之间实际上轮换执行。一、线程概述一、线程概述一台机器可以同时执行多个程序,一个进程可以通过一台机器可以同时执行多个程序,一个进程可以通过运行多个线程来并发地执行多项任务。运行多个线程来并发地执行多项任务。JavaJava虚拟机通虚拟机通过过多线程机制多线程机制来来提高程序运行的效率提高程序运行的效率。基于进程的特点:基于进程的特点:基于进程的特点:基于进程的特点:允许计算机同时运行允许计算机同时运行两个或更多的程序两个或更多的程序。基于线程的多任务处理环境中,线程是最小的处理基于线程的多任务处理环境中,线程是最小的处理单位。单位。每个进程每个进程的内部数据和状态
7、都是完全独立的。的内部数据和状态都是完全独立的。一个进程内的多线程一个进程内的多线程是共享一块内存空间和一组系是共享一块内存空间和一组系统资源,有可能互相影响。统资源,有可能互相影响。线程的切换比进程切换的负担要小。线程的切换比进程切换的负担要小。线程的优点线程的优点 方便调度和通信方便调度和通信方便调度和通信方便调度和通信。与进程相比,多线程是一种非常。与进程相比,多线程是一种非常“节俭节俭”的的多任务操作方式多任务操作方式。恰当地使用线程,可以降低开发和维护的开销,并且能够提恰当地使用线程,可以降低开发和维护的开销,并且能够提高复杂应用的性能,改进应用程序响应速度。高复杂应用的性能,改进应
8、用程序响应速度。改进应用程序响应改进应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使用多线程技术,将耗时长的操作置于一个新的线程,可以避免这种尴尬的情况。提高系统效率提高系统效率提高系统效率提高系统效率。特别是使多。特别是使多CPUCPU系统更加有效,操作系统系统更加有效,操作系统会保证当线程数不大于会保证当线程数不大于CPUCPU数目时,不同的线程运行于不数目时,不同的线程运行于不同的同的CPUCPU上。上。改善程序结构改善程序结构改善程序结构改善程序结构。一个既长又复杂的进程可以考虑分为多个。一个既长又
9、复杂的进程可以考虑分为多个线程,成为几个独立或半独立的运行部分,这样的程序会线程,成为几个独立或半独立的运行部分,这样的程序会利于理解和修改利于理解和修改。二、编写线程程序二、编写线程程序 在在JavaJava中建立线程有两种方法中建立线程有两种方法:一种是一种是继承继承ThreadThread类类,另一种是另一种是实现实现RunnableRunnable接口接口 其实这两种方法从本质上说是一种方法,即都是通其实这两种方法从本质上说是一种方法,即都是通过过ThreadThread类类来建立线程,并来建立线程,并运行运行runrun方法的。方法的。但它们的大区别是通过继承但它们的大区别是通过继承
10、ThreadThread类来建立线程,类来建立线程,虽然在实现起来更容易,但由于虽然在实现起来更容易,但由于JavaJava不支持多继承不支持多继承,因此,这个线程类如果继承了因此,这个线程类如果继承了ThreadThread,就不能再继,就不能再继承其他的类了,因此,承其他的类了,因此,JavaJava线程模型提供了线程模型提供了通过通过实实现现RunnableRunnable接口接口的的方法来建立线程,这样线程类可方法来建立线程,这样线程类可以在必要的时候继承和业务有关的类,而不是以在必要的时候继承和业务有关的类,而不是ThreadThread类类。建立线程的两种方法的比较建立线程的两种方
11、法的比较1.可以将代码和数据分开,形成清晰的模型;2.还可以从其他类继承;3.保持程序风格的一致性。1.不能再从其他类继承;2.编写简单,可以直接操纵线程,无需使用Thread.currentThread()。使用使用Runnable接口接口直接继承直接继承ThreadThread类类Java程序设计 2013线程的基本控制方法线程的基本控制方法方法方法方法方法说明说明说明说明start()start()线程方法,新建的线程进入线程方法,新建的线程进入RunnableRunnable状态状态 wait()wait()对象方法,释放对象锁,线程进入对象方法,释放对象锁,线程进入blockedbl
12、ocked状态,等状态,等待被待被notifynotify或时间到期或时间到期notify()/notifynotify()/notifyAll()All()对象方法,唤醒其他的线程对象方法,唤醒其他的线程 yield()yield()线程静态方法,放弃执行,回到线程静态方法,放弃执行,回到RunnableRunnable状态,使其状态,使其他优先级不低于此线程的线程有机会先运行他优先级不低于此线程的线程有机会先运行sleep()sleep()线程静态方法,线程睡眠指定的一段时间,线程进入线程静态方法,线程睡眠指定的一段时间,线程进入blockedblocked状态状态join()join()
13、线程方法,调用这个方法的线程,会等待加入的子线线程方法,调用这个方法的线程,会等待加入的子线程完成程完成isAlive()isAlive()判断某一个线程是否还在运行判断某一个线程是否还在运行runrun,RunRun方法结束返回方法结束返回false false sleep()sleep()方法方法l该方法用来使一个线程该方法用来使一个线程暂停运行暂停运行一段固定的时间,一段固定的时间,在线程睡眠在线程睡眠时间内,将运行别的线程;时间内,将运行别的线程;sleepsleep()()结束后,线程将进入结束后,线程将进入就绪就绪(RunnableRunnable)状态。状态。lsleep()sl
14、eep()方法的格式有两种:方法的格式有两种:static void sleep(int mills)static void sleep(int mills)throws InterruptedExceptionthrows InterruptedException /休眠时间以休眠时间以msms为单位为单位static void sleep(long millis,static void sleep(long millis,int nanos)throws int nanos)throws InterruptedException InterruptedException /休眠时间,指毫秒
15、数与纳秒数之和休眠时间,指毫秒数与纳秒数之和例程:每隔一秒钟打印一个数字到屏幕1.public class Timer extends Thread2.int time=1;3.public Timer(int time)4.this.time=time;5.6.public void run()7.try8.for(int i=1;i=time;i+)9.Thread.sleep(1000);10.System.out.println(i);11.12.catch(InterruptedException e)13.System.out.println(e.toString();14.15.
16、16.public static void main(String args)17.Timer timer=new Timer(10);18.timer.start();19.20.多线程的执行顺序多线程的执行顺序l多个线程运行时,调度策略为固定优先级调度,级别多个线程运行时,调度策略为固定优先级调度,级别相同时,由操作系统按时间片来分配。相同时,由操作系统按时间片来分配。l下面给出的例子中下面给出的例子中,共运行三个线程共运行三个线程,它们做同样的事它们做同样的事,每次打印循环次数和自己的序列号每次打印循环次数和自己的序列号,运行结果表明运行结果表明,它它们并不是连续运行的。们并不是连续运行
17、的。1.class MultiThread extends Thread2.int threadNum;3.public static void main(String args)4.multithread array=new MultiThread 3;5.for(int i=0;i3;i+)6.arrayi=new MultiThread(i+1);7.for(int i=0;i3;i+)8.arrayi.start();9.10.MultiThread(int SerialNum)11.super();12.threadNum=SerialNum;13.14.publicvoidrun(
18、)15.intMySerialNum=0;16.for(intj=1;j=10;j+)17.MySerialNum+;18.try19.Thread.sleep(1000);20.catch(Exceptione)21.System.out.println(e.toString();22.23.System.out.println(loop:+MySerialNum);24.System.out.println(thread:+threadNum+bye.);25.26.27.Java程序设计 2013yield()yield()方法方法l调用该方法将调用该方法将CPUCPU让给具有与当前线程
19、相同优先级让给具有与当前线程相同优先级的线程。的线程。l如果没有同等优先级的线程是如果没有同等优先级的线程是RunnableRunnable状态,状态,yieldyield()()方法将什么也不做。方法将什么也不做。19.class Hello extends Thread20.int i;21.public void run()22.while(true)23.System.out.println(Hello+i+);24.if(i=5)break;25.lt.joint.join()()方法使当前的线程方法使当前的线程等待,直到,直到 t t 结结束为止,线程恢复到束为止,线程恢复到运行运
20、行(runnable)(runnable)状态。状态。l有三种调用格式:有三种调用格式:join():join():如当前线程发出调用如当前线程发出调用t.joint.join()(),则,则当前线程将等待线程当前线程将等待线程 t t结束后再继续执行。结束后再继续执行。join(long join(long millismillis):):如当前线程发出调用如当前线程发出调用t.joint.join()(),则当前线程将等待线程,则当前线程将等待线程t t结束或最多等结束或最多等待待millsmills毫秒后在继续执行。毫秒后在继续执行。join(long join(long millis,
21、longmillis,long nanosnanos)join()方法方法其他方法其他方法isDaemon()isDaemon()和和setDaemon()setDaemon()方法方法在包含多个线程的应用程序中,线程间有时会共享存储空间。当两个或多个线程同时访问同一共享资源时,必然会出现冲突问题。如,一个线程可能尝试从一个文件中读取数据,而另一个线程则尝试在同一文件中修改数据。在这种情况下,数据可能会变的不一致,例程P400、P402。需要做的是允许一个线程彻底完成其任务后,再允许下一个线程执行。必须保证一个共享资源一次只被一个线程使用。实现此目的的过程称为同步。同步是Java程序设计的重要
22、技术。四、多线程同步处理四、多线程同步处理多线程同步的基本原理多线程同步的基本原理l多个并发线程之间共用资源,则需要进行同步处理多个并发线程之间共用资源,则需要进行同步处理同步问题(1)静态方法和非静态方法静态方法和非静态方法同步问题(2)同一个实例对象的多个同步方法同步问题(3)同步语句块同步问题(4)同步顺序多线程同步处理多线程同步处理同步问题同步问题(2)(2)在多线程同步中在多线程同步中同一个实例对象的多个同步方法同一个实例对象的多个同步方法同步问题同步问题(3)-(3)-同步语句块同步语句块l例程P413-414(1 1)阅读代码)阅读代码(2 2)分析输出结果)分析输出结果(3 3
23、)图)图11.511.5,J_BlockClassJ_BlockClass的类对象锁的类对象锁同步问题同步问题(4)-(4)-同步顺序同步顺序五、多线程的同步问题五、多线程的同步问题l死锁问题l粒度问题多线程的同步问题多线程的同步问题 -死锁问题死锁问题多线程的同步问题多线程的同步问题 同步的粒度问题同步的粒度问题Java程序设计 2013练习练习l在在java程序中,下列关于线程的说法错误的是程序中,下列关于线程的说法错误的是()A.线程启动调用线程启动调用start方法方法B.线程的主体是线程的主体是run方法方法C.线程运行中调用线程运行中调用sleep方法可以进入阻塞状态方法可以进入阻
24、塞状态D.在在java中,优先级的数值为中,优先级的数值为1的线程可以抢占优先级为的线程可以抢占优先级为5的线程的资的线程的资源源Java程序设计 2013练习:若编译和运行下列代码,出现的结果将是练习:若编译和运行下列代码,出现的结果将是_?1.public class MyThread implements Runnable 2.String myString=Yes;3.public void run()4.this.myString=No;5.6.public static void main(String args)7.MyThread t=new MyThread();8.new
25、Thread(t).start();9.for(int i=0;i 10;i+)10.System.out.print(t.myString);11.12.A、打印、打印 yes yes yes yes yes yes yes yes yes yes B、打印打印 no no no no no no no no no noC、打印、打印 yes no yes no yes no yes no yes no D、打印结果无法确定打印结果无法确定Java程序设计 2013练习:若编译和运行下列代码,出现的结果将是练习:若编译和运行下列代码,出现的结果将是1.publicclassMyAddexte
26、ndsThread2.staticinttotal=10;3.intn;4.publicMyAdd(intn)5.this.n=n;6.7.publicvoidrun()8.try9.sleep(n);10.total=total+n;11.System.out.println(total);12.catch(Exceptione)13.System.out.println(“EXCEPTION!”);14.15.16.publicstaticvoidmain(Stringargs)17.MyAddt1=newMyAdd(3000);18.MyAddt2=newMyAdd(1000);19.t
27、1.start();20.t2.start();21.22.运行结果:10104010Java程序设计 2013练习:阅读下面的程序,修改程序中错误的地方练习:阅读下面的程序,修改程序中错误的地方 1.public class Test implements Runnable 2.String str=new String10;3.for(int i=0;i str.length();i+)4.stri=i+”-”;5.6.public void run()7.try 8.for(int i=0;i str.length();i+)9.sleep(1000);10.System.out.pri
28、nt(stri);11.12.catch(InterruptedException e)13.e.printStackTrace();14.15.16.public static void main(String args)17.Test t=new Test();18.t.run();19.20.Java程序设计 2013多线程同步问题多线程同步问题小结小结对多线程程序本身来说,它会对系统产生以下影响:对多线程程序本身来说,它会对系统产生以下影响:1)1)线程需要线程需要占用内存占用内存。2)2)线程过多,会线程过多,会消耗大量消耗大量CPUCPU时间来跟踪线程时间来跟踪线程。3)3)必须考虑多线程同时访问共享资源的问题,如果必须考虑多线程同时访问共享资源的问题,如果没有协调好,就会产生令人意想不到的问题,例没有协调好,就会产生令人意想不到的问题,例如可怕的如可怕的死锁和资源竞争死锁和资源竞争。4)4)因为同一个任务的所有线程都共享相同的地址空因为同一个任务的所有线程都共享相同的地址空间,并共享任务的全局变量,所以程序也必须考间,并共享任务的全局变量,所以程序也必须考虑多线程虑多线程同时访问全局变量同时访问全局变量的问题。的问题。线程例程.docxJAVA多线程编程集合.pdf深入学习深入学习