• / 23
  • 下载费用:10 金币  

第8章 多线程机制.ppt

关 键 词:
第8章 多线程机制.ppt
资源描述:
第8章 多线程机制,8.1 线程基础 8.2 线程控制 8.3 线程同步 8.4 注意事项,8.1 线程基础 8.1.1 进程和线程,计算机的操作系统可以同时执行多个任务。听歌的同时能够打字、下载文件,在聊天窗口打字的时候对方还能通过视频看到你。 多任务是指在一个系统中可以同时运行多个程序,即有多个独立运行的任务,每一个任务对应一个进程。 由于一个CPU在同一时刻只能执行一个程序中的一条指令。实际上,多任务运行的并发机制使这些任务交替运行,因间隔时间短,所以感觉就是多个程序在同时运行。 Java语言使用多线程来实现一个程序中的多个任务同时运行。程序员可以在程序中执行多个线程,每个线程完成一个功能,并与其他,8.1 线程基础 8.1.1 进程和线程,计算机的操作系统可以同时执行多个任务。听歌的同时能够打字、下载文件,在聊天窗口打字的时候对方还能通过视频看到你。 多任务是指在一个系统中可以同时运行多个程序,即有多个独立运行的任务,每一个任务对应一个进程。 由于一个CPU在同一时刻只能执行一个程序中的一条指令。实际上,多任务运行的并发机制使这些任务交替运行,因间隔时间短,所以感觉就是多个程序在同时运行。 Java语言使用多线程来实现一个程序中的多个任务同时运行。程序员可以在程序中执行多个线程,每个线程完成一个功能,并与其他线程并发执行,这种机制称为多线程。,进程(process)是程序的一次执行过程,是操作系统运行程序的基本单位。程序是静态的,进程是动态的。系统运行一个程序就是一个进程从创建、运行到消亡的过程。 系统可以为一个程序同时创建多个进程。每一个进程都有自己独立的一块内存空间和一组系统资源,即使同类进程之间也不会共享系统资源。,操作系统,进程1,进程2,进程3,线程1,线程2,线程3,线程具有生命周期,它包含3个状态:出生状态、就绪状态、运行状态。 出生状态:用户在创建线程时处于的状态,在用户使用该线程实例调用start()方法之前都处于出生状态。 就绪状态:用户调用start()之后,线程就处于就绪状态了。 运行状态:当线程得到系统资源后就进入运行状态。,8.1.2线程的生命周期,出生,就绪,执行,等待,休眠,死亡,阻塞,Thread t=new Thread();,t.start(),t.notify()或 t.notifyAll(),时间片结束,得到系统资源,t.wait(),t.sleep(),t.run(),例8.1 获取当前线程对象,并输出当前线程的名称。 public class MainThread {public static void main(String[] args) {System.out.println(“main主方法开始运行“);Thread currentThread = Thread.currentThread();System.out.println(“成功获取当前线程对象“);String name = currentThread.getName();System.out.println(“当前线程的名称是:“+name);} },8.1.3 认识main线程,Thread类是Java语言的线程类,位于java.lang包中。 该类的实例对象是线程对象,所以继承该类编写线程子类是实现多线程的方法之一。 通过Thread类创建线程子类的格式为: class 线程的类名 extends Thread{ public void run(){ 程序语句}} Thread类的start()方法用于启动一个线程对象。 public void start() 执行该方法后,JVM启动该线程对象,并调用该线程的run()方法。,8.1.4 通过继承Thread类创建线程,例8.2 在项目中创建Writer作者类,该类继承Thread类并重写run()方法称为线程类,在主方法中创建两个作者类的实例对象,分别设置name属性为“张三”和“李四”,然后同时启动两个线程,在控制台查看两个线程的运行情况。,8.1.4 通过继承Thread类创建线程,public class Writer extends Thread {private String name=“未知“; // 声明作者名public Writer(String name) {this.name=name; } // 初始化作者名称public void run() { // 重写run()方法while (true) {System.out.println(name+“:写一段文稿“); // 输出工作进度System.out.println(name+“:吸一口烟,放松一下。“); // 输出工作状态 try {Thread.sleep((int) (Math.random() * 10000)); // 随机休息几秒}catch (InterruptedException e) {e.printStackTrace();}} }public static void main(String[] args) {Thread writer1 = new Writer(“张三“); // 创建作者1线程Thread writer2 = new Writer(“\t李四“); // 创建作者2线程writer1.start(); // 张三线程开始工作writer2.start(); // 李四线程同时启动} },图 8.2 运行结果,(1) Application应用程序运行时总是调用main方法,因此main是创建和启动线程对象的地方。main本身也是一个线程,是程序自动拥有的一个线程,称为主线程。在main方法中创建了两个testThread线程对象: writer1与writer2,并在创建后马上调用start方法启动了这两个线程。 (2) 从输出的结果可以看出两个线程的名字是交替显示的,这是因为两个线程是同步的,于是,两个run方法也同时被执行。线程语句的顺序只是决定于线程执行的顺序,线程的执行顺序是由系统调度和控制的。,(3) 由继承Thread创建的子类,必须覆盖run方法,因为Thread线程类的run方法是空的。run是线程类的关键方法,线程的所有活动都是通过它来实现的。当调用线程对象时系统就自动调用其run方法,正是通过run方法才使创建线程的目的得以实现。run方法的作用如同Application应用程序的main方法一样。 由例子可以看出,创建线程对象,就是设计run方法。一旦启动线程对象,就进入run方法,便执行run中的所有语句,run方法执行完毕,这个线程也就结束了。,当一个类是从其他类继承时,如继承Frame类。此时就不能再继承Thread类来创建线程。这时可以通过接口Runnable直接创建线程对象。接口Runnable是一个抽象接口,接口中只声明了一个未实现的run方法。 package java.lang; public interface Runnable{public abstract void run(); } 实现Runnable接口的对象需要传递给Thread类的构造方法,通过Thread构造方法去创建线程类,也就是说Runnable接口的实现对象需要传递给Thread的实例对象才能启动线程。 Thread(Runnable target) Thread(Runnable target,String name),8.1.5 通过Runnable接口创建线程,使用Runnable接口启动新线程的步骤如下:,(1)建立Runnable接口实例对象。 (2)以Runnable接口实例对象创建Thread实例对象。 (3)调用Thread线程对象的start()方法启动线程。,Thread对象,,Runnable对象,启动线程,执行run()方法中的代码,根据Runnable对象创建Thread对象,调用start()方法,例8.2 创建窗体,在窗体中布局一个文本域组件。见案例RunnableDemo.java,两种创建线程方法的比较: (1) 由继承Thread类创建线程对象简单方便,可以直接操作线程,但不能再继承其他类; (2) 在继承其他类的类中可用Runnable接口创建线程对象。可保持程序风格的一致性。,1、线程的休眠:try{ Thread.sleep(2000);}catch(InterruptedException e){e.printStackTrace();},8.2 线程控制,2、线程的停止: 早期JDK版本中使用stop()方法停止线程,新版本中废除了。现在提倡在run()方法中使用布尔型标记控制循环的停止。 例如: public class InterruptedTest implements Runnable{private boolean isContinue=false; public void run(){while(true){……if(isContinue) break;} } public void setContinue(){this.isContinue=true;} },3、 线程的调度 当前某程序为多线程程序,假如存在一个线程A,此时需要插入线程B,并要求线程B先执行完毕,然后在继续执行线程A,这时可以使用join()方法。就好比你正在看电视却突然有人上门收水费,你必须付完水费才能继续看电视。见案例JoinTest.java,在单线程程序中,每次只能做一件事情,后面的事情也需要等待前面的事情完成后才可以进行,如果使用多线程程序,虽然能够实现多处理,但是会发生两个以上的线程抢占资源的问题,例如两个人同时使用一个麦克风,多个人同时向同一个账户汇款等。在多线程编程中,必须防止这些资源访问的冲突。 Java提供线程同步的机制可以防止资源访问的冲突。,8.3 线程的同步机制,8.3.1 线程安全火车站售票系统-------在代码中判断网络中当前剩余票数是否大于0,如果大于0则执行售票功能 -------当两个线程同时访问这段代码时(假如这时只剩下1张票),第一个线程将票售出------------- 第二个线程已经执行完成判断是否有票的操作,并得出结论票数〉0,这样它售出票那么就会产生负数。见案例ThreadSaftTest.java,8.3.2 线程同步机制 如何解决资源共享的问题,基本上所有解决多线程资源冲突问题的方法,都是在指定时间段内只允许一个线程访问共享资源,这时就需要给共享资源上一道锁了。 1。同步块 synchronized (object){……//业务代码 } object:同步块锁定的对象 通常将共享资源的操作放置在synchronized定义的代码内,这样其它线程也获取到这个锁时,必须等待代码块的对象锁被释放时才能进入该区域。 案例ThreadSafeTest.java是对ThreadSaftTest.java的修改。2。同步方法 synchronized void syncMethod(。。。。。。) { 。。。。。。//方法体 } 档某个对象调用了同步方法,其它方法必须等待该同步方法执行完毕才能被执行。所以将每个能访问共享资源的方法修饰为synchronized可以防止多个县城同时修改或访问共享资源。见案例ThreadSafe.java,考虑到多线程时,人们立刻会想到某些任务是可以使用多线程的,例如数据计算、数据库查询,以及输入的获得。因为这些任务通常都被认为是后台任务,不直接与用户打交道。在Java语言程序设计中,动态效果的程序都会使用多线程,例如动画的播放、动态的字幕,等等。,8.4 何时使用多线程及注意问题,在程序中使用多线程是有代价的。它会对系统产生以下影响: (1) 线程需要占用内存; (2) 线程过多,会消耗大量CPU时间来跟踪线程; (3) 必须考虑多线程同时访问共享资源的问题,如果没有协调好,就会产生令人意想不到的问题,例如可怕的死锁和资源竞争; (4) 因为同一个任务的所有线程都共享相同的地址空间,并共享任务的全局变量,所以程序也必须考虑多线程同时访问全局变量的问题。,
展开阅读全文
  微传网所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
0条评论

还可以输入200字符

暂无评论,赶快抢占沙发吧。

关于本文
本文标题:第8章 多线程机制.ppt
链接地址:https://www.weizhuannet.com/p-10036191.html
微传网是一个办公文档、学习资料下载的在线文档分享平台!

网站资源均来自网络,如有侵权,请联系客服删除!

 网站客服QQ:80879498  会员QQ群:727456886

copyright@ 2018-2028 微传网络工作室版权所有

     经营许可证编号:冀ICP备18006529号-1 ,公安局备案号:13028102000124

收起
展开