您好,欢迎访问三七文档
当前位置:首页 > 办公文档 > 招标投标 > java课件-多线程
1多线程第七章2本章内容线程的概念模型线程的创建和启动线程的状态控制线程的同步3什么是进程进程就是一个在内存中独立运行的程序,有自己的地址空间。如正在运行的写字板程序就是一个进程“多任务”:指操作系统能同时运行多个进程(程序)。如WIN2K系统可以同时运行写字板程序、画图程序、WORD、EXCEL等4什么是线程线程:是进程内部单一的一个顺序控制流。线程和进程每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。线程:轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。多线程:在同一个进程中有多个顺序流同时执行5线程的概念模型虚拟的CPU,由java.lang.Thread类封装和虚拟CPU所执行的代码,传递给Thread类对象。CPU所处理的数据,传递给Thread类对象。代码数据虚拟CPUJava线程模型6线程体Java的线程是通过java.lang.Thread类来实现的。每个线程都是通过某个特定Thread对象所对应的方法run()来完成其操作的,方法run()称为线程体(即线程的可执行代码)。7多线程文件输入输出装置各种系统资源数据区段程序区段只有一个地方在执行文件输入输出装置各种系统资源数据区段程序区段同时有数个地方在执行传统的进程多线程的任务8主线程在任何Java程序启动时,一个线程立刻运行(即main方法对应的线程),该线程通常称为程序的主线程。主线程的特点:它是产生其他子线程的线程。它不一定是最后完成执行的线程,子线程可能在它结束之后还在运行。9创建线程有两种方法用来创建线程:1.声明一个Thread类的子类,并覆盖run()方法。classmythreadextendsThread{publicvoidrun(){/*覆盖该方法*/}}2.声明一个实现Runnable接口的类,并实现run()方法。classmythreadimplementsRunnable{publicvoidrun(){/*实现该方法*/}}用start()方法启动线程:Threadt1=newThread();T1.start();10java.lang.Thread类这个类包含了创建和运行线程所需的一切东西构造函数:publicThread();publicThread(Runnabletarget);publicThread(Stringname);参数说明:name:新线程对象的名字11java.lang.Thread类2-1常用方法:publicvoidstart();//启动该线程,将导致run方法被自动调用。该方法将立即返回,新线程将运行publicvoidrun();//必须覆盖该方法,在方法体中添加你想要在该线程中执行的代码publicstaticvoidsleep(longmillis)throwsInterruptedException;//使当前正在执行的线程睡眠指定的时间publicvoidinterrupt();//用于将一个中断请求发送给线程publicstaticbooleaninterrupted();//用于测试当前线程(即正在执行该指令的线程)是否已经被中断publicbooleanisInterrupted();//用于测试某个线程是否已经被中断publicfinalbooleanisAlive();//用于测试某个线程是否还活着publicfinalvoidsetPriority(intnewPriority);//设置线程的优先级12java.lang.Thread类2-2publicfinalvoidjoin(longmillis)throwsInterruptedException;//使某个线程等待指定的时间。调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行。publicfinalintgetPriority();//获得线程的优先级publicstaticThreadcurrentThread();返回代表当前正在执行的线程的Thread对象publicstaticvoidyield();使当前正在执行的线程临时暂停,以使其它的线程运行publicfinalvoidwait(longtimeout)throwsInterruptedException;当前线程被中断,并进入到一个对象的等待列表中,直到另外的线程调用同一个对象上的notify()或notifyAll()方法publicfinalvoidnotify();用于将对象等待列表中的任选的一个线程唤醒,使它再次成为可运行的线程publicfinalvoidnotifyAll();用于将对象等待列表中的所有线程唤醒,使它们再次成为可运行的线程13java.lang.Runnable接口该接口只有一个方法:publicvoidrun();实现该接口的类必须覆盖该方法。实现了Runnable接口的类并不具有任何天生的线程处理能力,这与那些从Thread类继承的类是不同的。为了从一个Runnable对象产生线程,必须再单独创建一个线程对象,并把Runnable对象传递给它。14两种创建线程方法的比较使用Runnable接口可以将代码和数据分开,形成清晰的模型;还可以从其他类继承;保持程序风格的一致性。直接继承Thread类不能再从其他类继承;编写简单,可以直接操纵线程,无需使用Thread.currentThread()。15创建多线程publicclassTestThread{//主类publicstaticvoidmain(Stringargs[]){Runnerr=newRunner();//生成线程类对象rThreadt1=newThread(r);//创建线程对象t1Threadt2=newThread(r);//创建线程对象t2t1.start();//启动线程t1t2.start();//启动线程t2}}classRunnerimplementsRunnable{//线程类publicvoidrun(){for(inti=0;i20;i++){System.out.println(No.+i);}}}16多线程共享数据和代码线程虚拟CPU代码数据t1Thread类对象t1Runner类中的run方法Runner类型对象rt2Thread类对象t2Runner类中的run方法Runner类型对象r对上例进行分析,可以得到下表:17join方法使用示例publicclassTestThread5{publicstaticvoidmain(String[]args){Runner5r=newRunner5();Threadt=newThread(r);t.start();try{t.join();//主线程main将中断,直到线程t执行完毕}catch(InterruptedExceptione){}for(inti=0;i50;i++){System.out.println(主线程:+i);}}}classRunner5implementsRunnable{publicvoidrun(){for(inti=0;i10;i++)System.out.println(SubThread:+i);}}18线程的优先级在java中,每一个线程都有一个优先级。默认情况下,一个线程将继承其父线程的优先级。线程的优先级用数字来表示,范围从1到10,一个线程的缺省优先级是5Thread.MIN_PRIORITY=1Thread.MAX_PRIORITY=10Thread.NORM_PRIORITY=5使用下述线方法获得或设置线程对象的优先级intgetPriority();voidsetPriority(intnewPriority);19数据的完整性在大多数实际运行的多线程应用程序中,两个或多个线程需要共享对同一个对象的访问。如果两个线程访问同一个对象,并且每个线程都调用一个方法修改该对象的状态,会出现什么情况?由于多个线程运行时执行顺序是交叉的,根据数据被访问的顺序,将会产生受损坏的对象。这种情况通常称为争用条件(racecondition)线程1线程2线程10对象变量取过来加1后送回去对象状态和想象的不一样啊,咋整?!20对象的监视器(锁)在java中,每个对象都包含了一把锁(也叫作“监视器”),它自动成为对象的一部分(不必为此写任何特殊的代码)。在给定时刻,只有一个线程可以拥有一个对象的锁示例:线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入withdrawal()线程1监视器线程221同步(synchronized)为了确保在任何时刻一个共享对象只被一个线程使用,必须使用“同步(synchronized)”有两种方式实现同步:–使用同步方法synchronizedvoidmethodA(){}–使用同步块synchronized(obj){//obj是被锁定的对象//要同步的语句}用synchronized来标识的块或方法即为监视器监视的部分。只有使用synchronized,才能利用对象的监视器功能。22wait-notify机制当synchronized方法中的wait方法被调用时,当前线程将被中断运行,并且放弃该对象的锁。一旦线程调用了wait方法,它便进入该对象的等待列表。要从等待列表中删除该线程,使它有机会继续运行,其它线程必须调用同一个对象上的notify或者notifyAll方法。当线程再次成为可运行的线程后,它们便试图重新进入该对象。一旦可以使用该对象锁时,其中的一个线程将锁定该对象,并且从它上次调用wait方法后的位置开始继续运行23使用同步机制如果两个或多个线程修改一个对象,请将执行修改的方法声明为synchronized方法。受到对象修改影响的只读方法也必须实现同步不要在synchronized方法中花费大量的时间。大多数操作只是更新数据,然后很快返回24每当一个方法改变某个对象的状态时,它就应该调用notifyAll方法。这样可以给等待线程一个机会,以便查看环境有没有发生变化记住,wait和notifyAll/notify方法都属于Object类的方法,而不是Thread类的方法。反复检查你对wait方法的调用与同一对象上的通知是否匹配25死锁当所有的线程都在等待得到某个资源后才能继续运行下去时,整个程序将被挂起,这种情况就叫做死锁图例:线程2pen线程1note把“pen”给我,我才能给你“note”把“note”给我,我才能给你“pen”26wait-notify使用示例信息板例子。read()方法在读信息之前先等待,直到信息可读,读完后通知要写的线程。write()方法在写信息之前先等待,直到信息被取走,写完后通知要读的线程。输出结果如下:27小结1.实现线程有两种方法:实现Ruannable接口继承Thread类2.在小应用程序中通常在start中创建线程3.当新线程被启动时,java调用该线程的run方法,它是Thread的核心4.线程的状态5.线程间的通信方式有三种:完全共享数据,通过监视器,通过join28小结6.两个或多个线程竞争资源时,需要用同步的方法协调资源7.多个线程执行时,要用到同步方法,即使用synchronized的关键字设定同步区8.wait和notify起协调作用
本文标题:java课件-多线程
链接地址:https://www.777doc.com/doc-4214773 .html