java课件-多线程

上传人:101****457 文档编号:89231776 上传时间:2019-05-21 格式:PPT 页数:28 大小:143.50KB
返回 下载 相关 举报
java课件-多线程_第1页
第1页 / 共28页
java课件-多线程_第2页
第2页 / 共28页
java课件-多线程_第3页
第3页 / 共28页
java课件-多线程_第4页
第4页 / 共28页
java课件-多线程_第5页
第5页 / 共28页
点击查看更多>>
资源描述

《java课件-多线程》由会员分享,可在线阅读,更多相关《java课件-多线程(28页珍藏版)》请在金锄头文库上搜索。

1、1,多线程,第七章,2,本章内容,线程的概念模型 线程的创建和启动 线程的状态控制 线程的同步,3,什么是进程,进程就是一个在内存中独立运行的程序,有自己的地址空间 。如正在运行的写字板程序就是一个进程 “多任务”:指操作系统能同时运行多个进程(程序)。如WIN2K系统可以同时运行写字板程序、画图程序、WORD、EXCEL等,4,什么是线程,线程:是进程内部单一的一个顺序控制流。 线程和进程 每个进程都有独立的代码和数据空间(进程上下文),进程切换的开销大。 线程: 轻量的进程,同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换的开销小。 多线程: 在同一个进程

2、中有多个顺序流同时执行,5,线程的概念模型,虚拟的CPU,由java.lang.Thread类封装和虚拟 CPU所执行的代码,传递给Thread类对象。 CPU所处理的数据,传递给Thread类对象。,代 码,数 据,虚拟CPU,Java线程模型,6,线程体,Java的线程是通过java.lang.Thread类来实现的。 每个线程都是通过某个特定Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体(即线程的可执行代码)。,7,多线程,文件,输入输出装置,各种系统资源,数据区段,程序区段,只有一个地方在执行,文件,输入输出装置,各种系统资源,程序区段,同时有数个地

3、方在执行,传统的进程,多线程的任务,8,主线程,在任何Java程序启动时,一个线程立刻运行(即main方法对应的线程),该线程通常称为程序的主线程。 主线程的特点: 它是产生其他子线程的线程。 它不一定是最后完成执行的线程,子线程可能在它结束之后还在运行。,9,创建线程,有两种方法用来创建线程: 声明一个 Thread 类的子类,并覆盖 run() 方法。 class mythread extends Thread public void run( ) /* 覆盖该方法*/ 声明一个实现 Runnable 接口的类,并实现 run() 方法。 class mythread implements

4、 Runnable public void run( ) /* 实现该方法*/ 用start()方法启动线程: Thread t1 = new Thread(); T1.start();,10,java.lang.Thread类,这个类包含了创建和运行线程所需的一切东西 构造函数: public Thread(); public Thread(Runnable target); public Thread(String name); 参数说明: name:新线程对象的名字,11,java.lang.Thread类 2-1,常用方法: public void start();/启动该线程,将导致

5、run方法被自动调用。该方法将立即返回,新线程将运行 public void run();/必须覆盖该方法,在方法体中添加你想要在该线程中执行的代码 public static void sleep(long millis) throws InterruptedException;/使当前正在执行的线程睡眠指定的时间 public void interrupt();/用于将一个中断请求发送给线程 public static boolean interrupted();/用于测试当前线程(即正在执行该指令的线程)是否已经被中断 public boolean isInterrupted();/用于

6、测试某个线程是否已经被中断 public final boolean isAlive();/用于测试某个线程是否还活着 public final void setPriority(int newPriority);/设置线程的优先级,12,java.lang.Thread类 2-2,public final void join(long millis) throws InterruptedException;/使某个线程等待指定的时间。调用某线程的该方法,将当前线程与该线程“合并”,即等待该线程结束,再恢复当前线程的运行。 public final int getPriority() ; /获

7、得线程的优先级 public static Thread currentThread();返回代表当前正在执行的线程的Thread对象 public static void yield() ;使当前正在执行的线程临时暂停,以使其它的线程运行 public final void wait(long timeout) throws InterruptedException;当前线程被中断,并进入到一个对象的等待列表中,直到另外的线程调用同一个对象上的notify() 或notifyAll() 方法 public final void notify() ;用于将对象等待列表中的任选的一个线程唤醒,使

8、它再次成为可运行的线程 public final void notifyAll();用于将对象等待列表中的所有线程唤醒,使它们再次成为可运行的线程,13,java.lang.Runnable接口,该接口只有一个方法: public void run() ; 实现该接口的类必须覆盖该方法。 实现了Runnable接口的类并不具有任何天生的线程处理能力,这与那些从Thread类继承的类是不同的。 为了从一个Runnable对象产生线程,必须再单独创建一个线程对象,并把Runnable对象传递给它。,14,两种创建线程方法的比较,使用Runnable接口 可以将代码和数据分开,形成清晰的模型; 还可

9、以从其他类继承; 保持程序风格的一致性。 直接继承Thread类 不能再从其他类继承; 编写简单,可以直接操纵线程,无需使用 Thread. currentThread()。,15,创建多线程,public class TestThread /主类 public static void main(String args) Runner r = new Runner();/生成线程类对象r Thread t1 = new Thread(r);/创建线程对象t1 Thread t2 = new Thread(r);/创建线程对象t2 t1.start();/启动线程t1 t2.start();/启

10、动线程t2 class Runner implements Runnable /线程类 public void run() for(int i=0; i20; i+) System. out. println(“No. “ + i); ,16,多线程共享数据和代码,对上例进行分析,可以得到下表:,17,join方法使用示例,public class TestThread5 public static void main(String args) Runner5 r = new Runner5(); Thread t = new Thread(r); t.start(); try t.join(

11、);/主线程main将中断,直到线程t执行完毕 catch(InterruptedException e) for(int i=0;i50;i+) System.out.println(“主线程:“ + i); class Runner5 implements Runnable public void run() for(int i=0;i10;i+) System.out.println(“SubThread: “ + i); ,18,线程的优先级,在java中,每一个线程都有一个优先级。默认情况下,一个线程将继承其父线程的优先级。线程的优先级用数字来表示,范围从1到10,一个线程的缺省优先

12、级是5 Thread.MIN_PRIORITY = 1 Thread.MAX_PRIORITY = 10 Thread.NORM_PRIORITY = 5 使用下述线方法获得或设置线程对象的优先级 int getPriority(); void setPriority(int newPriority);,19,数据的完整性,在大多数实际运行的多线程应用程序中,两个或多个线程需要共享对同一个对象的访问。如果两个线程访问同一个对象,并且每个线程都调用一个方法修改该对象的状态,会出现什么情况? 由于多个线程运行时执行顺序是交叉的,根据数据被访问的顺序,将会产生受损坏的对象。这种情况通常称为争用条件(

13、race condition),线程1,线程2,线程10,对象,变量,取过来,加1后送回去,对象状态和想象的不一样啊,咋整?!,20,对象的监视器(锁),在java中,每个对象都包含了一把锁(也叫作“监视器”),它自动成为对象的一部分(不必为此写任何特殊的代码)。在给定时刻,只有一个线程可以拥有一个对象的锁 示例:线程1进入withdrawal方法时,获得监视器(加锁);当线程1的方法执行完毕返回时,释放监视器(开锁),线程2的withdrawal方能进入,21,同步(synchronized),为了确保在任何时刻一个共享对象只被一个线程使用,必须使用“同步(synchronized)” 有两

14、种方式实现同步: 使用同步方法 synchronized void methodA() 使用同步块 synchronized(obj)/obj是被锁定的对象 /要同步的语句 用synchronized来标识的块或方法即为监视器监视的部分。只有使用synchronized ,才能利用对象的监视器功能。,22,wait-notify 机制,当synchronized方法中的wait方法被调用时,当前线程将被中断运行,并且放弃该对象的锁。 一旦线程调用了wait方法,它便进入该对象的等待列表。要从等待列表中删除该线程,使它有机会继续运行,其它线程必须调用同一个对象上的notify或者notifyAl

15、l方法。 当线程再次成为可运行的线程后,它们便试图重新进入该对象。一旦可以使用该对象锁时,其中的一个线程将锁定该对象,并且从它上次调用wait方法后的位置开始继续运行,23,使用同步机制,如果两个或多个线程修改一个对象,请将执行修改的方法声明为synchronized方法。受到对象修改影响的只读方法也必须实现同步 不要在synchronized方法中花费大量的时间。大多数操作只是更新数据,然后很快返回,24,每当一个方法改变某个对象的状态时,它就应该调用notifyAll方法。这样可以给等待线程一个机会,以便查看环境有没有发生变化 记住,wait和notifyAll/notify方法都属于Ob

16、ject类的方法,而不是Thread类的方法。反复检查你对wait方法的调用与同一对象上的通知是否匹配,25,死锁,当所有的线程都在等待得到某个资源后才能继续运行下去时,整个程序将被挂起,这种情况就叫做死锁 图例:,26,wait-notify使用示例,信息板例子。read()方法在读信息之前先等待,直到信息可读,读完后通知要写的线程。write()方法在写信息之前先等待,直到信息被取走,写完后通知要读的线程。 输出结果如下:,27,小结,1. 实现线程有两种方法: 实现Ruannable接口 继承Thread类 2. 在小应用程序中通常在start中创建线程 3.当新线程被启动时,java调用该线程的run方 法,它是Thread的核心 4. 线程的状态 5. 线程间的通信方式有三种:完全共享数据,通过监视器,通过join,28,小结,6. 两个或多

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 中学教育 > 其它中学文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号