您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 质量控制/管理 > Java程序设计(十一)
Java程序设计第十一章多线程程序设计山东科技大学信息科学与工程学院2编写线程程序线程的生命周期多线程的同步处理多线程的同步问题主要内容3编写线程程序(1)Java虚拟机通过多线程机制来充分利用计算机的各种资源,并提高程序的运行效率。一个程序可以包含多个线程,各线程用于实现不同的功能。Java中构造线程有两种方法:1)继承java.lang.Thread的子类;2)实现接口java.lang.Runnable;4编写线程程序(2)线程类java.lang.Thread的主要成员方法:原型描述publicvoidstart()启动线程publicvoidrun()线程的执行代码,包含了线程所要实现的功能publicstaticvoidsleep(longmillis)throwsInterruptedException让当前线程休眠millis毫秒,注:此方法是静态方法,不属于任何线程对象。通过构造类Thread的子类创建线程:J_Thread.java5编写线程程序(3)通过类Thread创建和启动线程的步骤1)编写子类继承类java.lang.Thread;2)编写子类的run方法;3)通过:new子类(构造方法参数列表)创建线程;4)调用子类的start方法将该线程加入到线程调度列表;5)调用子类的sleep方法可使线程休眠,让出CPU执行权限。P386,J_Thread.java6编写线程程序(4)线程接口java.lang.Runnable只有一个成员方法:通过Runnable接口编写线程类的一般步骤如下:原型描述publicvoidrun()线程的执行代码,包含了线程所要实现的功能publicclassAextendsBimplementsRunnable{//类的其他代码publicvoidrun(){//线程主体}//类的其他代码}//Aa=newA();Threadt=newThread(a);t.start();1.编写线程类2.构造和启动线程7编写线程程序(5)通过Runnable接口编写线程类示例(J_ThreadRunnable.java,P389):publicclassJ_ThreadRunnableimplementsRunnable{privateintm_threadID;publicJ_ThreadRunnable(inti){m_threadID=i;System.out.println(创建线程:+i);}//J_ThreadRunnable构造方法结束publicvoidrun(){for(inti=0;i3;i++){System.out.println(运行线程:+m_threadID);try{Thread.sleep((int)(Math.random()*1000));}catch(InterruptedExceptione){System.err.println(异常InterruptedException:+e);e.printStackTrace();}//try-catch结构结束}//for循环结束}//方法run结束publicstaticvoidmain(Stringargs[]){Threadt1=newThread(newJ_ThreadRunnable(1));t1.start();Threadt2=newThread(newJ_ThreadRunnable(2));t2.start();System.out.println(方法main结束);}//方法main结束}//类J_ThreadRunnable结束8编写线程程序-后台线程(1)线程分为:后台线程(DaemonThread)和用户线程(UserThread)。线程默认为用户线程。后台线程:主要用于为程序中其他线程提供服务。当一个程序中只有后台线程运行时,程序会立即退出。当一个程序中还有用户线程运行时,程序不会退出。java.lang.Thread与后台线程相关的方法如下:原型描述publicfinalbooleanisDaemon()用户判断一个线程是用户线程还是后台线程,是后台线程返回true,否则返回false;publicfinalvoidsetDaemon(booleanon)on为true则将当前线程设置为后台线程;on为false则将当前线程设置为用户线程。注:此方法必须在start()方法之前调用。9编写线程程序-后台线程(2)后台线程示例(P391)J_ThreadDaemon.java用户线程示例(P391)J_ThreadUser.javamain方法结束后,系统会终止各个后台线程。main方法结束后,各个线程仍然在运行。10编写线程程序-线程组(1)一个线程组包含多个线程或多个线程组,这种包含关系使得线程之间会形成树状的父子结构。java.lang.ThreadGroup用于管理线程。ThreadGroup的构造方法如下:将一个线程加入到线程组中则需调用如下方法来构建线程:原型描述publicThreadGroup(Stringname)name指定线程组名称publicThreadGroup(ThreadGroupparent,Stringname)name指定线程组名称parent用于指定父线程组。原型描述publicThread(ThreadGroupgroup,Stringname)name指定将要加入线程组的线程名称group用于指定将要加入的线程组。11编写线程程序-线程组(2)线程组示例(J_ThreadGroup.java,P394)publicclassJ_ThreadGroup{publicstaticvoidmain(Stringargs[]){System.out.print(方法main所在的线程组含有);System.out.println(Thread.activeCount()+个线程);Threadt=Thread.currentThread();ThreadGrouptg=t.getThreadGroup();for(;tg!=null;tg=tg.getParent()){System.out.print(线程组+tg.getName());System.out.print(含有);System.out.println(tg.activeCount()+个线程);intn=tg.activeCount();Thread[]tList=newThread[n];intm=tg.enumerate(tList);for(inti=0;im;i++)System.out.println(其中第+(i+1)+个线程名为+tList[i].getName());}//for循环结束}//方法main结束}//类J_ThreadGroup结束12编写线程程序-线程组(3)Thread的相关成员方法:ThreadGroup的相关成员方法:原型描述publicstaticintactiveCount()返回当前线程组的线程个数publicstaticThreadcurrentThead()返回当前的线程publicfinalThreadGroupgetParent()返回该线程所在的线程组publicfinalStringgetName()返回线程的名称原型描述publicfinalThreadGroupgetParent()返回该线程组的父线程组publicstaticintactiveCount()返回估算的线程组下的所有线程publicintenumerate(Thread[]list)将该线程组及其以下线程组的所有线程拷贝到数组list中,并返回所有线程的数量publicintenumerate(ThreadGroup[]list)将该线程组及其以下线程组的所有线程组拷贝到数组list中,并返回所有线程组的数量13编写线程程序线程的生命周期多线程的同步处理多线程的同步问题主要内容14线程的生命周期(1)线程一般要经历:新生态、就绪态、运行态和死亡态等4个基本状态,在运行过程中,可能会进入阻塞态、等待态和睡眠态。线程的生命周期如下图所示:15线程的生命周期(2)线程的优先级:1)线程的调度依赖于线程的优先级。2)每个线程都有优先级,优先级范围为Thread.MIN_PRIORITY-Thread.MAX_PRIORITY,即1-10。3)线程默认的优先级为:Thread.NORM_PRIORITY(5)。4)java.lang.Thread与优先级相关的方法如下:5)java.lang.ThreadGroup与优先级相关的方法如下:原型描述publicfinalintgetPriority()返回当前线程的优先级publicfinalvoidsetPriority(intnewPriority)设置当前线程的优先级为newPriority原型描述publicfinalintgetMaxPriority()返回该线程组所允许的最大优先级。publicfinalvoidsetMaxPriority(intpri)设置该线程组所允许的最大优先级为pri16编写线程程序线程的生命周期多线程的同步处理多线程的同步问题主要内容17多线程的同步处理多线程之间会共享资源,多线程的同步处理是为了让多线程协调并发地工作,保证程序运行正确。Java虚拟机中使用同步方法和同步语句块来实现同步处理。同步处理会产生死锁问题,在设计时要注意避免。18多线程的同步处理-多线程共享内存引发的问题(1)在实验室进行数据更新和分析的例程(J_Synchronization.java,P400)程序分析:1)实验员更新数据,分析员分析数据;2)问题出现在:分析员分析数据的过程中,实验员又更新了数据,从而可能导致分析结果不正确。19多线程的同步处理-多线程共享内存引发的问题(2)多线程访问共享内存引发问题的例程(J_ThreadSum.java,P402):加减法失败。程序分析:1)m_data是类静态成员域,实际是上t1和t2的共享数据;2)t1和t2的并发运行会导致加1或减1的操作无法正确完成。20多线程的同步处理-多线程同步的基本原理(1)为了正确地并发访问共享数据,Java虚拟机采用了锁机制来实现多线程的同步处理。Java虚拟机既可对实例对象加锁,也可对类对象加锁。类对象的引用可通过类java.lang.Class的如下成员方法获取:静态成员属于类对象,非静态成员属于实例对象。publicstaticClassforName(StringclassName)throwsClassNotFoundException21多线程的同步处理-多线程同步的基本原理(2)锁机制原理示意图22多线程的同步处理-多线程同步的基本原理(3)锁机制原理:Java虚拟机为每个对象配备了一把锁(lock)和一个等候集(waitset)。对于每个加锁对象,实际锁住的是一些同步方法和同步语句块。通过锁机制,可确保任何同一时刻内最多只有一个线程能够运行与该对象相关联的同步方法和同步语句块。1)同步方法只要在方法前加上Synchronized即可。2)同步语句块语法格式如下:Synchronized(引用类型的表达式){语句块。}说明:引用类型的表达式可指向类对象或实例对象。23多线程的同步处理-多线程同步的基本原理(4)线程可通过在同步方法或同步语句块中调用java.lang.Object的notify和notifyAll方法来激活等候集中的线程。如果线程在等候集中的timeout时限已到,则该线程会自动被激活,进入就绪态。原型描述publicfinalvoidnotify()随机激活等候集中的一个线程publicfinalvoidnotifyAll()激活等候集中的所
本文标题:Java程序设计(十一)
链接地址:https://www.777doc.com/doc-2881241 .html