java语言与编程第11章 java多线程

上传人:xiao****1972 文档编号:72169810 上传时间:2019-01-22 格式:PPT 页数:19 大小:247.81KB
返回 下载 相关 举报
java语言与编程第11章 java多线程_第1页
第1页 / 共19页
java语言与编程第11章 java多线程_第2页
第2页 / 共19页
java语言与编程第11章 java多线程_第3页
第3页 / 共19页
java语言与编程第11章 java多线程_第4页
第4页 / 共19页
java语言与编程第11章 java多线程_第5页
第5页 / 共19页
点击查看更多>>
资源描述

《java语言与编程第11章 java多线程》由会员分享,可在线阅读,更多相关《java语言与编程第11章 java多线程(19页珍藏版)》请在金锄头文库上搜索。

1、第11章 Java多线程,11.1 线程的概念,现代操作系统中为了实现程序的并发执行而引入 了进程的概念.进程是程序的一次执行过程,是动态 的概念.线程是比进程更小的执行单位,是进程内部 独立的,有序的指令流. 多线程编程的含义是指可将程序任务分成几个并 行的子任务,特别是在网络编程时,使用多线程思想 编写的程序会具有很好的运行效率,可以充分利用系 统资源.,11.2 线程的创建,在Java中创建线程有两种方法:一种方法是通过创Thread 类的子类来实现,另一种方法是通过实现Runnable接口的类 来实现. 11.2.1 Thread类与Runnnable接口 就像应用程序必须从main(

2、)方法开始执行一样,一个线程 必须从run()方法开始执行,而run()方法声明在java.lang. Runnable接口中. 1.Runnable接口 Runnable接口中只声明了一个run()方法:public void run(),在创建并启动一个线程后,系统自动调用run()方法.而 Runnable中的run()方法只是一个没有实现的方法.一个线程 对象必须实现run()方法来完成线程的所有活动,已实现的 run()方法称为该对象的线程体.,11.2 线程的创建(续),2.Thread类 Thread类在java.lang包中定义,其构造函数如下: public Thread()

3、 public Thread(Runnable target) public Thread(Runnable target,String name) Thread(String name) Thread(ThreadGroup group, Runnable target) Thread(ThreadGroup group, Runnable target,String name) Thread(ThreadGroup group, String name),11.2 线程的创建(续),11.2.2 继承Thread类实现多线程 创建线程最简单的方法就是继承Thread类,这个 类已经为线程的

4、创建和运行做了必要的配置,并且提 供了大量的方法来方便我们控制自己的各个线程. run()方法是Thread类最重要的方法,它被Thread类 的start()方法调用. 例:SimpleThread.java,public class SimpleThread extends Thread int count= 1, number; public SimpleThread(int num) number = num; System.out.println(“创建线程 “ + number); public void run() while(true) System.out.println(“

5、线程 “ + number + “:计数 “ + count); if(+count= 4) return; public static void main(String args ) for(int i = 0; i 3; i+) new SimpleThread(i+1).start(); ,11.2 线程的创建(续),11.2.3 通过Runnable接口实现多线程 用继承Thread类的方法创建线程简单明了,但是 有一个缺点,就是如果类已经继承了一个父类,则不 能再继承Thread类.此时可以使用创建线程的另外 一种方法,即首先创建实现Runnable接口的类,再建 立该类的对象,以此

6、对象作为参数建立Thread类的 对象,最后调用Thread类对象的start方法启动线程.,11.2 线程的创建(续),例:Runnable1.java,通过实现Runnable接口实现多线程. public class Runnable1 implements Runnable int k=0; public Runnable1(int k) this.k = k; public void run() int i = k; while (i50) System.out.print(i+“ “); i+=2; ,11.2 线程的创建(续),public static void main (S

7、tring args ) Runnable1 r1 = new Runnable1(1) ; /创建具有线程体的目标对象 Runnable1 r2 = new Runnable1(2) ; Thread t1=new Thread(r1); /以目标对象创建线程 Thread t2=new Thread(r2); t1.start(); t2.start(); for (int i=0;i40;i+) System.out.print(“A “); 注:程序中,线程语句的顺序只决定了线程产生的顺序,线程产生后并不立即执行,而是和系统中的所有其他线程一起等待系统来执行它,这时所有线程执行的机会是

8、均等的,所以这些线程的执行顺序由系统调度和控制,不由程序决定.,11.3 线程优先级与线程调度策略,为了区分线程对操作系统以及对用户的重要性, Java定义了线程的优先级控制和调度策略. 11.3.1 线程优先级 Java将线程的优先级分为10个等级,分别用110 之间的数字表示,数字越大表示线程的优先级越高.相 应的,在Thread类中定义了表示线程最低,最高和普 通优先级的MIN_PRIORITY, MAX_PRIORITY和 NORMAL_PRIORITY,分别代表优先级等级1,10和5. 一个线程被创建时,默认的优先级为5.新建线程将继 承创建它的父线程的优先级.,11.3 线程优先级

9、与线程调度策略(续),在应用程序中设置线程的优先级用setPriority() 方法,用getPriority()方法可以获得当前线程的优先 级,这两个方法的定义为: setPriority(int newPriority) getPriority() 在Java中有一种特殊的线程:守护(daemon)线程, 它具有最低的优先级,用于为系统中的其他对象和线 程提供服务.例如,始终在运行的垃圾收集器就是一 个daemon线程.,11.3 线程优先级与线程调度策略(续),11.3.2 线程调度策略 在单CPU系统上以某种顺序运行多个线程,称为线 程调度. Java的线程调度策略是一种基于优先级的抢

10、占式 调度策略.抢占式调度分为:独占方式和分时方式. 独占方式下,当前执行的线程将一直执行下去,直 到执行完毕或由于某种原因主动放弃CPU,或CPU被 一个更高优先级的线程抢占. 分时方式下,当前运行线程获得一个时间片,时间 片用完,即使没有执行完也要让出CPU,进入可运行 状态,等待下一个时间片的调度.例:ThreadPriorityDemo.java,11.3 线程优先级与线程调度策略(续),11.3.3 Thread类中提供的线程调度的方法 public static void sleep(long millis)使当前执行的线程睡眠指定的时间 例:TestInterrupt.java

11、public static void sleep(long millis,int nanos) public static void yield() 调用yield方法,可以使具有当前线程相同优先级 的线程有运行的机会.如果有其他线程具有相同的优 先级并且处于可运行状态,yield方法将把调用yield 方法的线程放入可运行线程池,允许其他线程执行; 反之,如果不存在,则yield方法什么也不做,当前线程 将继续运行.例:TestYield.java,11.3 线程优先级与线程调度策略(续),public final void join()使当前线程暂停执行,等待调用该方法的线程结束后再继续执

12、行本线程. 例:TestJoin.java public void wait()是从Object继承来的,它使当前线程主动释放互斥锁,并进入互斥锁的等待队列.它的作用是使当前线程暂停执行,等待某一事件的发生,当这一事件发生时,一般通过调用notify或notifyAll方法来唤醒该线程. public void wait(long millis)等待被唤醒或者再 最多等待millis毫秒后自动执行.,11.3 线程优先级与线程调度策略(续),public void interrupt()为线程设置一个中断标记 public final void notify()唤醒等待队列中的一个线程,但是不

13、能指定唤醒哪个线程,任何满足了被唤醒条件的线程都有可能被唤醒 public final void notifyAll()唤醒等待队列中的所有线程,11.3 线程优先级与线程调度策略(续),11.3.4 线程的状态 在一个线程的生命周期中,它总处于某一种状态 (1)创建状态:处于此状态时,它仅仅是一个空的线程对象,系统不为其分配资源 (2)就绪状态:在就绪队列中等待系统为其分配资源 (3)可运行状态:系统为线程分配了它所需要的资源 (4)运行中状态:线程占用CPU运行 (5)阻塞状态:线程可能因为调用了sleep方法,或者等待资源等而不得不让出CPU (6)死亡状态:线程执行结束,自然撤消或被停

14、止.,11.4 线程的同步与死锁,11.4.1 线程的同步 前面的线程都是异步的,即每个线程中都包含了运 行时所需的所有数据和方法,而不需要外部的资源和 方法,此时它不必关心其他线程的状态和行为.但很 多情况下一些线程需要共享数据.例如,一个线程向 文件中写数据,另一个线程从文件中读数据,此时就 要实现同步.例:TestSync.java 通常将系统中使用某类资源的线程称为消费者,而 产生和释放同类资源的线程称为生产者,这即是线程 同步的一般模型:生产者-消费者问题.,11.4 线程的同步与死锁(续),例:生产者生产从09的整数,消费者负责读取”生产” 的数据,我们希望生产者每生产一个数据,消费者就 会将这个数据消费掉. WithoutSynchronization.java Synchronization.java,11.4 线程的同步与死锁,11.4.2 线程的死锁 例:TestDeadLock.java,

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

当前位置:首页 > 高等教育 > 大学课件

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