高级Java程序设计第三章多线程教师:徐莉班级:计科10&网工102目录•3.1多线程编程基础•3.2线程的生命周期•3.3线程的优先级•3.4本章小结33.1多线程编程基础•本节内容▫线程的概念▫Thread类▫Runnable接口▫线程间的数据共享▫多线程的同步控制▫线程之间的通信▫后台线程43.1.1线程的概念•多进程▫一个独立程序的每一次运行称为一个进程,例如用字处理软件编辑文稿时,同时打开mp3播放程序听音乐,这两个独立的程序在同时运行,称为两个进程▫进程要占用相当一部分处理器时间和内存资源▫进程具有独立的内存空间通信很不方便,编程模型比较复杂3.1多线程编程基础5•多线程▫一个程序中多段代码同时并发执行,称为多线程▫线程比进程开销小,协作和数据交换容易▫Java是第一个支持内置线程操作的主流编程语言多数程序设计语言支持多线程要借助于操作系统“原语(primitives)”3.1多线程编程基础3.1.1线程的概念问题探究•1.在实验一或实验二中找1-2个你认为设计最好的程序,分析其执行的流程。然后,和同学交流你的设计。(积极上讲台和全班同学交流设计经验者,平时分加10分)•2.通过对一些java应用程序的分析,你能总结出一般程序运行结束的位置吗?举例说明。(十一后交作业)▫提示:先考虑一个方法(函数)运行结束的位置73.1.2Thread类•Thread类▫直接继承了Object类,并实现了Runnable接口。位于java.lang包中▫封装了线程对象需要的属性和方法▫继承Thread类——创建多线程的方法之一从Thread类派生一个子类,并创建子类的对象子类应该重写Thread类的run方法,写入需要在新线程中执行的语句段。调用start方法来启动新线程,自动进入run方法。3.1多线程编程基础8例3-1在新线程中完成计算某个整数的阶乘publicclassFactorialThreadTester{publicstaticvoidmain(String[]args){System.out.println(mainthreadstarts);FactorialThreadthread=newFactorialThread(10);thread.start();//将自动进入run()方法System.out.println(mainthreadends);}}3.1多线程编程基础9classFactorialThreadextendsThread{privateintnum;publicFactorialThread(intnum){this.num=num;}publicvoidrun(){inti=num;ntresult=1;System.out.println(newthreadstarted);while(i0){result=result*i;i=i-1;}System.out.println(Thefactorialof+num+is+result);System.out.println(newthreadends);}}例3-1(续)3.1多线程编程基础10例3-1运行结果•运行结果mainthreadstartsmainthreadendsnewthreadstartedThefactorialof10is3628800newthreadends•结果说明▫main线程已经执行完后,新线程才执行完▫main函数调用thread.start()方法启动新线程后并不等待其run方法返回就继续运行,thread.run函数在一边独自运行,不影响原来的main函数的运行3.1多线程编程基础11•源程序修改▫如果启动新线程后希望主线程多持续一会再结束,可在start语句后加上让当前线程(这里当然是main)休息1毫秒的语句:try{Thread.sleep(1);}catch(Exceptione){};例3-1修改:延长主线程3.1多线程编程基础12•修改后运行结果mainthreadstartsnewthreadstaredThefactorialof10is3628800newthreadendsmainthreadends•运行结果说明▫新线程结束后main线程才结束•作业:•探究:多线程运行的流程?例3-1修改后运行结果3.1多线程编程基础13Thread类常用API方法名称说明publicThread()构造一个新的线程对象,默认名为Thread-n,n是从0开始递增的整数publicThread(Runnabletarget)构造一个新的线程对象,以一个实现Runnable接口的类的对象为参数。默认名为Thread-n,n是从0开始递增的整数publicThread(Stringname)构造一个新的线程对象,并同时指定线程名publicstaticThreadcurrentThread()返回当前正在运行的线程对象publicstaticvoidyield()使当前线程对象暂停,允许别的线程开始运行publicstaticvoidsleep(longmillis)使当前线程暂停运行指定毫秒数,但此线程并不失去已获得的锁旗标。3.1多线程编程基础14publicvoidstart()启动线程,JVM将调用此线程的run方法,结果是将同时运行两个线程,当前线程和执行run方法的线程publicvoidrun()Thread的子类应该重写此方法,内容应为该线程应执行的任务。publicfinalvoidstop()停止线程运行,释放该线程占用的对象锁旗标。publicvoidinterrupt()中断此线程publicfinalvoidjoin()如果此前启动了线程A,调用join方法将等待线程A死亡才能继续执行当前线程publicfinalvoidjoin(longmillis)如果此前启动了线程A,调用join方法将等待指定毫秒数或线程A死亡才能继续执行当前线程Thread类常用API函数3.1多线程编程基础15publicfinalvoidsetPriority(intnewPriority)设置线程优先级publicfinalvoidsetDaemon(Booleanon)设置是否为后台线程,如果当前运行线程均为后台线程则JVM停止运行。这个方法必须在start()方法前使用publicfinalvoidcheckAccess()判断当前线程是否有权力修改调用此方法的线程publicvoidsetName(Stringname)更改本线程的名称为指定参数publicfinalbooleanisAlive()测试线程是否处于活动状态,如果线程被启动并且没有死亡则返回trueThread类—常用API函数3.1多线程编程基础16•例3-2创建3个新线程,每个线程睡眠一段时间(0~6秒),然后结束publicclassThreadSleepTester{publicstaticvoidmain(String[]args){//创建并命名每个线程TestThreadthread1=newTestThread(thread1);TestThreadthread2=newTestThread(thread2);TestThreadthread3=newTestThread(thread3);System.out.println(Startingthreads);thread1.start();//启动线程1thread2.start();//启动线程2thread3.start();//启动线程3System.out.println(Threadsstarted,mainends\n);}}3.1多线程编程基础17classTestThreadextendsThread{privateintsleepTime;publicTestThread(Stringname){super(name);sleepTime=(int)(Math.random()*6000);}publicvoidrun(){try{System.out.println(getName()+goingtosleepfor+sleepTime);Thread.sleep(sleepTime);//线程休眠}catch(InterruptedExceptionexception){};System.out.println(getName()+finished)}}例3-2(续)3.1多线程编程基础18•运行结果StartingthreadsThreadsstarted,mainendsthread1goingtosleepfor3519thread2goingtosleepfor1689thread3goingtosleepfor5565thread2finishedthread1finishedthread3finished•说明▫由于线程3休眠时间最长,所以最后结束,线程2休眠时间最短,所以最先结束▫每次运行,都会产生不同的随机休眠时间,所以结果都不相同例3-2运行结果3.1多线程编程基础193.1.3Runnable接口•Runnable接口▫Thread类实现了Runnable接口▫只有一个run()方法▫更便于多个线程共享资源▫Java不支持多继承,如果已经继承了某个基类,便需要实现Runnable接口来生成多线程▫以实现runnable的对象为参数建立新的线程▫start方法启动线程就会运行run()方法3.1多线程编程基础20publicclassFactorialThreadTester{publicstaticvoidmain(String[]args){System.out.println(mainthreadstarts);FactorialThreadt=newFactorialThread(10);//实现了Runnable的newThread(t).start();//运行FactorialThread的runSystem.out.println(newthreadstarted,mainthreadends);}}例3-3使用Runnable接口实现例3-1功能3.1多线程编程基础21classFactorialThreadimplementsRunnable{privateintnum;publicFactorialThread(intnum){this.num=num;}publicvoidrun(){inti=num;intresult=1;while(i0){result=result*i;i=i-1;}System.out.println(Thefactorialof+num+is+result);System.out.println(newthreadends);}}例3-3(续)3.1多线程编程基础22publicclassThreadSleepTester{publicstaticvoidmain(String[]args){TestThreadthread1=newTestThread();TestThreadthread2=newTestThread();TestThreadthread3=newTestThread();System.out.println(Startingthreads);newThread(thread1,Thread1).start();newThread(thread2,Thread2).start();newThread(thread3,Thread3).start();System.out.println(Threadsstarted,mainends\n);}}例3-4使用Runnable接口实现例3-2功能3.1多线程编程基础23classTestThreadimplementsRunnable{privateints