1 / 23

厦门大学数据库实验室 JAVA 多线程编程演示

厦门大学数据库实验室 JAVA 多线程编程演示. 报告人:谢荣东 导师:林子雨 2014 年 7 月 26 日. 进程和线程. 进程和线程都是一个控制流程。 一个进程通常对应于一个程序。 一个程序可以由多个不同的线程构成。. 进程. 程序:利用编程语言开发的一个工具软件, 静态的,在没有启动运行之前只是磁盘中的一个普通文件 进程 : 程序启动之后就变成了进程 动态 window 支持多进程,但 cpu 只有一个,所以同一时间只能运行一个进程 动态的 进程相互独立,不共享数据 线程:进程在运行过程中的执行走向,线索

Download Presentation

厦门大学数据库实验室 JAVA 多线程编程演示

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 厦门大学数据库实验室JAVA多线程编程演示 报告人:谢荣东 导师:林子雨 2014年7月26日

  2. 进程和线程 进程和线程都是一个控制流程。 一个进程通常对应于一个程序。 一个程序可以由多个不同的线程构成。

  3. 进程 程序:利用编程语言开发的一个工具软件, 静态的,在没有启动运行之前只是磁盘中的一个普通文件 进程:程序启动之后就变成了进程 动态 window 支持多进程,但cpu只有一个,所以同一时间只能运行一个进程 动态的 进程相互独立,不共享数据 线程:进程在运行过程中的执行走向,线索 单线程 : 如果只有一条单一线索 存在的问题 效率相对底下 没有充分合理的利用cpu 多线程 : 多于一条的执行走向线程 共享内存 可以实现多任务

  4. 进程 根据定义,进程为一个数据结构及能在其上进行的一次操作, • 它有两个基本特征, 1:进程是可用于资源的独立单位, 2:进程同时又是一个可独立调度和分派的基本单位, 这两个基本属性使之能够独立运行,也能够并发运行。但是在并发运行的时候,系统还需要执行一系列操作: 1、需要创建进程,并为之分配其所必需的资源。 2、撤销进程,对资源进行回收。 3、进程切换,它需要保留当前进程的CPU环境和设置新选中进程的CPU环境。 为此需要花费不少处理时间。正因为进程拥有资源,所以在并发执行进程的时候, 在创建、撤销和切换,系统需要付出较大的开销,因此,系统中设置的进程不能太多, 进程切换的频率也不能过高,这就限制了并发程度的提高。 为了解决这一问题,于是产生并引入了线程概念。

  5. 进程 进程:正在进行的程序 我们现在使用的操作系统都是多任务的,即能够 同时 执行多个应用程序。实际是操作系统负责对CPU等设备资源进行分配和管理,虽然这些设备某一时刻只能做一件事情,但以非常小的时间间隔交替执行多个程序,就给人同时执行多个程序的感觉。如从C盘复制文件到D盘的同时从E盘复制文件到F盘。

  6. 线程(threads) • 线程因为具有许多进程所具有的特征,因此被称为 轻量级 进程。计算机科学术语,指运行中程序的调度单位。 • 线程是进程中的实体,一个进程可以拥有多个线程,一个线程必须有一个父进程。 • 线程不拥有系统资源,只拥有运行必须的一些数据结构;它与父进程的其它线程共享该进程所拥有的全部资源。 • 线程可以创建和撤消,从而实现程序的并发执行。 • 一般,线程具有就绪、阻塞和运行三种基本状态。

  7. 线程 一个进程中可以包含一个或多个线程,一个线程就是程序内部的一条执行线索。 在单线程中,程序代码按调用顺序依次往下执行,不能实现两段程序代码同时交替运行的效果。如果一个程序中要实现两段程序代码同时交替运行,就需要产生多个线程,并指定每个线程上所要运行的程序代码段,这就是多线程。 程序启动运行时,就自动产生了一个线程,main方法就是在这个线程上运行的,当不再产生新的线程时,程序就是单线程。

  8. 多线程 多线程在实际工作场景的应用: QQ聊天(键盘的输入与等待)、 访问网页(应用服务器必须能响应多个用户请求) 创建多线程的方法有2种: 继承Thread类 实现Runnable接口

  9. Thread Java的线程通过Thread类来控制,一个Thread类的对象代表一个线程,而且只能代表一个线程。 通过Thread类和它定义的对象,我们能获得当前线程对象、获取某一线程的名称、可以实现控制线程暂停一段时间等功能。 每个线程都是通过某个特定Thread对象所对应的方法run( )来完成其操作的,方法run( )称为线程体。 使用start()方法,线程进入Runnable(可运行)状态,它将向线程调度器注册这个线程。 调用start()方法并不一定马上会执行这个线程,正如上面所说,它只是进入Runnable 而不是Running。 注意,不要直接在程序中调用线程的run()方法。 见 线程图

  10. 线程状态 阻塞 Blocked 创建new dead 死亡 解除阻塞 阻塞事件 就绪 Runnable 运行 Running start() run() 运行完毕 线程调度

  11. Thread 在单线程中,main方法必须等到run方法返回后才能继续往下执行。 而多线程中,调用start方法启动线程,运行run方法后,main方法可以不必等待run方法返回就继续运行,而另一个线程在一边独自运行,并不影响原来的main方法的运行。

  12. Thread 1.要将一段代码放在一个新的线程上运行,该代码所在的类应该继承Thread 或 实现Runnable 接口,而需要执行的代码写在run方法里面。 2.启动一个线程,不是调用run方法,而是调用Thread对象的start方法。start方法将产生一个新的线程,并在该线程上运行该Thread对象中的run方法。运行的其实是我们的类(Thread子类)的run方法,多态。 3.run方法执行完后,线程也就结束了,所以,我们可以通过控制run方法中的循环条件来控制线程的终止。

  13. 继承Thread • public class TestThread { • public static void main(String[] args) { • MyThread myThread = new MyThread(); • myThread.setName("myThread");//设置线程的名称 • myThread.start();//启动线程 • for(int i=0;i<100;i++){ • //主线程 • System.out.println(Thread.currentThread().getName() + “***" + i); • } • } • } • class MyThread extends Thread { • //需要在线程中运行的代码写在run方法中 • public void run() { • for (int i = 0; i < 100; i++) { • //获得当前执行的线程的名称 • System.out.println(Thread.currentThread().getName() + "---" + i); • } • } • }

  14. Runnable 通过实现Runnable接口并实现接口中定义的唯一抽象方法run(),可以创建一个线程。

  15. 实现Runnable接口 • public class TestRunnable{ • public static void main(String[] args){ • MyThread2 my = new MyThread2();//创建一个Runnable接口实现类 • Thread thread = new Thread(my);//把my传递给Thread类 • thread.setName("线程-1"); • thread.start(); • for(int i = 0;i<100;i++){ • System.out.println(Thread.currentThread().getName()+"***"+i); • } • } • } • class MyThread2 implements Runnable{ • //重写Runnable中的run抽象方法,写入需要执行的代码 • public void run(){ • for(int i=0;i<100;i++){ • System.out.println(Thread.currentThread().getName()+"--"+i); • } • } • }

  16. 线程的生命周期 • 与人有生老病死一样,线程也同样要经历 新建(new) 和其它的Java对象一样,只分配内存空间和初始化成员变量 就绪(runnable) 调用了start方法后进入就绪状态,什么时候运行取决线程调度器 运行(running) 获得了时间片开始执行run方法体 阻塞(blocked) 时间片用完,系统会剥夺其占有的资源,让其他线程有机会执行,优先级高的先执行 死亡(dead) run方法体执行完,正常结束或抛出Exception或Error 或 调用stop方法(不推荐) 五种状态。

  17. 分析两种实现多线程的方式: 写一个程序,模拟4个售票窗口共同卖100张火车票的程序。 1:使用继承Thread类方式实现。 2:使用实现Runnable接口方式实现。

  18. 继承Thread,每个线程卖了100张票 [没有共享数据] • public class TicketThread { • public static void main(String[] args){ • // 执行继承Thread的线程 • new MyThread().start(); • new MyThread().start(); • new MyThread().start(); • new MyThread().start(); • } • } • class MyThread extends Thread { • // 车票数量 • private int tickets = 100; • public void run() { • while (tickets > 0) { • System.out.println(this.getName()+"卖出第["+(tickets--)+"]张火车票"); } • } • }

  19. 实现Ruaable,线程总共卖100张票[有共享数据] • public class TicketRunnable { • public static void main(String[] args) { • //实现Runnable接口实现类 • myRunnable myR = new myRunnable(); • new Thread(myR).start(); • new Thread(myR).start(); • new Thread(myR).start(); • new Thread(myR).start(); • } • } • class myRunnable implements Runnable { • //火车票数量 • private int tickets = 100; • public void run() { • while (tickets > 0) { System.out.println(Thread.currentThread().getName()+"卖出第["+(tickets--) +"]张火车票."); • } • } • }

  20. 两种线程创建方式的比较 使用Runnable接口 实际工作中,几乎所有的多线程应用都用实现Runnable这种方式。 Runnable适合多个相同程序代码的线程去处理同一资源的情况。把虚拟CPU(线程)同程序的代码、数据有效的分离,较好的体现了面向对象的设计思想。 避免由于Java的单继承特性带来的局限性。也就是如果新建的类要继承其他类的话,因为JAVA中不支持多继承,就只能实现java.lang.Runnable接口。 有利于程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。 继承Thread类 不能再继承他类了。 编写简单,可以直接操纵线程,无需使用Thread.currentThread()。

  21. 总结 • 两种实现方式:Thread,Runnable • 线程状态:创建线程,就绪Runnable,运行Running,挂起Block,结束dead • 实现Runnable接口相对于继承Thread类的好处

  22. 展示坦克程序

  23. Thank You

More Related