2018/12/7 Java语言程序设计-多线程 教师:段鹏飞.

Slides:



Advertisements
Similar presentations
作者 : 陳鍾誠 單位 : 金門技術學院資管系 URL : 日期 : 2016/7/21 行程的同步 註:本章學術性較重,但考試常考。
Advertisements

软件编程基础 一、程序的编辑 Java 源程序是以 Java 为后缀的简单的文本文件,可以用各种 Java 集成开发环境中的源代码编辑器来编写,也可以用其他文 本编辑工具,如 Windows 中的记事本或 DOS 中的 EDIT 软件等。 利用文字编辑器编写下列程序 public class Hello.
Java 程序设计 第 8 章 多线程. 第 8 章 Java 的多线程 8.1 线程及其创建 Java 中的线程 Java 程序通过流控制来执行程序流,程序中单个顺序的流 控制称为线程, 多线程则指的是在单个程序中可以同时运行 多个不同的线程执行不同的任务。 单个程序内部也可以在同一时刻进行多种运算。
面向侧面的程序设计 方林博士 本文下载地址:
Linux 系统. 操作系统发展需求 1 没有操作系统 2 简单批处理操作系统 3 多道程序设计的批处理 4 多道程序设计的分时操作系统 5 多处理机并行系统 6 网络操作系统 7 分布式操作系统.
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
第七章 多线程处理 线程的互斥 线程的同步 死锁问题.
讓你的程式具有多工(Multitasking) 及多重處理(Multiprocessing)的能力
Java Programming Spring, 2010
四資二甲 第三週作業 物件導向程式設計.
第9章 Java多线程机制 9.1 Java中的线程 9.2 Thread的子类创建线程 9.3 使用Runable接口
第11章 Java多媒体技术.
Oracle数据库 Oracle 子程序.
线程与线程实现 主讲:赖国荣 QQ:
第二章 JAVA语言基础.
Ch07 介面與多重繼承 物件導向程式設計(II).
第九章 字符串.
Ch08 巢狀類別 物件導向程式設計(II).
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
Kvm异步缺页中断 浙江大学计算机体系结构实验室 徐浩.
Java语言程序设计 第七部分 多线程.
程式設計實作.
2018/12/3 面向对象与多线程综合实验-网络编程 教师:段鹏飞.
实践演练 广州创龙电子科技有限公司 01 广州创龙电子科技有限公司
走进编程 程序的顺序结构(二).
辅导课程六.
第10章 Java的线程处理 10.1 线程的基本概念 10.2 线程的属性 10.3 线程组 10.4 多线程程序的开发.
临界区软件互斥软件实现算法.
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第一次课后作业 1. C/C++/Java 哪些值不是头等程序对象 2. C/C++/Java 哪些机制采用的是动态束定
9.1 程式偵錯 9.2 捕捉例外 9.3 自行拋出例外 9.4 自定例外類別 9.5 多執行緒
本节内容 模拟线程切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
临界区软件互斥软件实现算法 主讲教师:夏莹杰
C/C++/Java 哪些值不是头等程序对象
用event class 从input的root文件中,由DmpDataBuffer::ReadObject读取数据的问题
4.2通讯服务模块线程之间传递信息 信息工程系 向模军 Tel: QQ:
Multithread 多執行緒 以GUI為例了解物件以及Event
第7章 Java 的多线程机制.
JAVA 编 程 技 术 主编 贾振华 2010年1月.
《JAVA程序设计》 语音答疑 辅导老师:高旻.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
C语言程序设计 主讲教师:陆幼利.
第二章 Java基本语法 讲师:复凡.
分裂对象模型 C++ otcl.
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
信号量(Semaphore).
本节内容 类成员的访问控制 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二章 Java语法基础.
iSIGHT 基本培训 使用 Excel的栅栏问题
西南科技大学网络教育系列课程 高级语程序设计(Java) 第八章 线程.
Chapter 18 使用GRASP的对象设计示例.
辅导课程十五.
第二章 Java基本语法 讲师:复凡.
临界区问题的硬件指令解决方案 (Synchronization Hardware)
本节内容 Windows线程切换_时钟中断切换 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
C++语言程序设计 C++语言程序设计 第一章 C++语言概述 第十一组 C++语言程序设计.
本节内容 动态链接库 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
第8章 创建与使用图块 将一个或多个单一的实体对象整合为一个对象,这个对象就是图块。图块中的各实体可以具有各自的图层、线性、颜色等特征。在应用时,图块作为一个独立的、完整的对象进行操作,可以根据需要按一定比例和角度将图块插入到需要的位置。 2019/6/30.
本节内容 进程 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
判斷(選擇性敘述) if if else else if 條件運算子.
创建、启动和关闭Activity 本讲大纲: 1、创建Activity 2、配置Activity 3、启动和关闭Activity
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
第二章 Java基础语法 北京传智播客教育
本节内容 SEMAPHORE 视频提供:昆山滴水信息技术有限公司 官网地址: 论坛地址: QQ交流 :
輸出執行結果到螢幕上 如果要將執行結果的文字和數值都「輸出」到電腦螢幕時,程式要怎麼寫? class 類別名稱 {
第二章 Java基本语法 讲师:复凡.
Summary
Presentation transcript:

2018/12/7 Java语言程序设计-多线程 教师:段鹏飞

1、进程和线程的区别 2、Thread和Runnable的区别 3、能够使用Thread或Runable创建线程 4、如何进行线程同步 2018/12/7 知识点 1、进程和线程的区别 2、Thread和Runnable的区别 3、能够使用Thread或Runable创建线程 4、如何进行线程同步

1958年,麦卡锡提出问题:A输入一个命令,需要10秒,电脑只需要1秒,电脑大部分时间在等待... 多用户多进程

多核时代的多进程

界面卡死

1、进程与线程的概念 2、Java中多线程的编程 3、线程的同步与死锁 主要内容 继承Thread类与使用Runnable接口

计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。 进程与线程的区别 计算机的核心是CPU,它承担了所有的计算任务。它就像一座工厂,时刻在运行。

假定工厂的电力有限,一次只能供给一个车间使用。也就是说,一个车间开工的时候,其他车间都必须停工。背后的含义就是,单个CPU一次只能运行一个任务。

进程 进程就好比工厂的车间,它代表CPU所能处理的单个任务。任一时刻,CPU总是运行一个进程,其他进程处于非运行状态。

调度策略 Java的调度方法 进程的调度 时间片 抢占式:高优先级的进程抢占CPU 同优先级线程组成先进先出队列,使用时间片策略 对高优先级,使用优先调度的抢占式策略 1 2

一个车间里,可以有很多工人。他们协同完成一个任务。

线程就好比车间里的工人,一个进程可以包括多个线程。

线程共享 车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。

多线程

可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。

一个防止他人进入的简单方法,就是门口加一把锁。先到的人锁上门,后到的人看到上锁,就在门口排队,等锁打开再进去。这就叫"互斥锁"(Mutual exclusion,缩写 Mutex),防止多个线程同时读写某一块内存区域。

还有些房间,可以同时容纳n个人,比如厨房。也就是说,如果人数大于n,多出来的人只能在外面等着。这好比某些内存区域,只能供给固定数目的线程使用。

这时的解决方法,就是在门口挂n把钥匙。进去的人就取一把钥匙,出来时再把钥匙挂回原处。后到的人发现钥匙架空了,就知道必须在门口排队等着了。这种做法叫做"信号量"(Semaphore),用来保证多个线程不会互相冲突。 不难看出,mutex是semaphore的一种特殊情况(n=1时)。也就是说,完全可以用后者替代前者。但是,因为mutex较为简单,且效率高,所以在必须保证资源独占的情况下,还是采用这种设计。

程序 进程 进程的特点 进程和线程 程序是一段静态的代码,它是应用程序执行的蓝本 进程是指一种正在运行的程序,有自己的地址空间 动态性 并发性 独立性

进程和线程 线程的定义 进程内部的一个执行单元,它是程序中一个单一的顺序控制流程。如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称之为多线程

进程与多线程

进程与线程 什么时候用进程,什么时候用线程? ——多线程是十字路口 多进程是立交桥。

多线程的优势 多线程使系统空转时间减少,提高CPU利用率 进程间不能共享内存,但线程之间共享内存非常容易 使用多线程实现多任务并发比多进程的效率高

线程要经历创建、就绪、运行、阻塞和死亡等5个状态 ,称为生命周期。 线程的生命周期 线程要经历创建、就绪、运行、阻塞和死亡等5个状态 ,称为生命周期。

2 线程的使用方法 1、创建Thread子类构造线程 2、实现Runnable接口构造线程

两种方法来创建线程 线程的创建和启动 继承Java.lang.Thread类,并覆盖run() 方法 实现Java.lang.Runnable接口,并实现run() 方法 class MyThread extends Thread { public void run( ) { /* 覆盖该方法*/ } class MyThread implements Runnable{ public void run( ) { /* 实现该方法*/ }

启动线程 线程的创建和启动 新建的线程不会自动开始运行,必须通过start( )方法启动 启动继承Thread的线程 启动实现Runnable接口的线程 MyThread t = new MyThread (); t.start(); MyThread mt = new MyThread (); Thread t = new Thread(mt); t.start();

继承Java.lang.Thread类 线程的创建和启动 public class ThreadDemo1 { public static void main(String args[]) { MyThread1 t = new MyThread1(); t.start(); while (true) { System.out.println("兔子领先了,别骄傲"); } class MyThread1 extends Thread { public void run() { System.out.println("乌龟领先了,加油"); Java程序启动时,会立刻创建主线程,main就是在这个线程上运行。当不再产生新线程时,程序是单线程的 演示示例:创建和启动多线程

实现Java.lang.Runnable接口 线程的创建和启动 实现Java.lang.Runnable接口 public class ThreadDemo2 { public static void main(String args[]) { MyThread2 mt = new MyThread2(); Thread t = new Thread(mt); t.start(); while (true) { System.out.println("兔子领先了,加油"); } class MyThread2 implements Runnable { public void run() { System.out.println("乌龟超过了,再接再厉"); 演示示例:创建和启动多线程

两种线程创建方式的比较 线程的创建和启动 继承Thread类方式的多线程 实现Runnable接口方式的多线程 优势:编写简单 劣势:无法继承其它父类 实现Runnable接口方式的多线程 优势:可以继承其它类,多线程可共享同一个Thread对象 劣势:编程方式稍微复杂,如果需要访问当前线程,需要调用Thread.currentThread()方法

线程的创建与启动 创建Thread子类构造线程 (1)创建一个Thread类的子类; (2)在子类中重新定义自己的run()方法,这个中包含了线程要实现的操作; (3)用关键字new 创建一个线程对象; (4)调用start()方法启动线程。

3、构造线程:Thread(Runnable对象名); 4、启动线程:线程对象.start( );

Thread类的常用方法 线程的创建和启动 方 法 功 能 static Thread currentThread() 得到当前线程 final String getName( ) 返回线程的名称 final void setName(String name) 将线程的名称设置为由name指定的名称 void start( ) 调用run( )方法启动线程,开始线程的执行 void run( ) 存放线程体代码

新生 可运行 阻塞 死亡 线程的状态 使用new关键字创建一个线程后,尚未调用其start方法之前 调用线程对象的start方法之后 这个状态当中,线程对象可能正在运行,也可能等待运行 阻塞 一种“不可运行”的状态,在得到一个特定的事件之后会返回到可运行状态 死亡 线程的run方法运行完毕或者在运行中出现未捕获的异常时

线程同步的必要性

使用多线程进行开发,让两个用户同时操作一个银行账户。每次取款100元,取款前先检查余额是否足够。如果不够,放弃取款 线程同步的必要性 使用多线程进行开发,让两个用户同时操作一个银行账户。每次取款100元,取款前先检查余额是否足够。如果不够,放弃取款 创建银行账户类Account 创建取款线程TestAccount 创建测试类TestWithdrawal,让两个用户同时取款

当多个线程访问同一个数据时,容易出现线程安全问题。需要让线程同步,保证数据安全 线程同步的必要性 当多个线程访问同一个数据时,容易出现线程安全问题。需要让线程同步,保证数据安全 线程同步 当两个或两个以上线程访问同一资源时,需要某种方式来确保资源在某一时刻只被一个线程使用 线程同步的实现方案 同步代码块 同步方法

在Java中,每个对象有一个“互斥锁”,该锁可用来保证在同一时刻只能有一个线程访问该对象。 锁的使用过程(当一个线程要操作一个对象时) 线程的同步与互斥 对象互斥锁 在Java中,每个对象有一个“互斥锁”,该锁可用来保证在同一时刻只能有一个线程访问该对象。 锁的使用过程(当一个线程要操作一个对象时) 准备 加锁 对象是否 已加锁 进入 临界区 执行操作 解锁 否 是

线程同步的实现 可以是任何存在的对象 synchronized(obj){ //此处代码为同步代码块 } 同步的代码内容

线程同步的实现

线程同步的实现 访问修饰符 synchronized 返回类型 方法名{ }

死锁 线程同步的好处 线程同步的缺点 死锁 解决了线程安全问题 性能下降 会带来死锁 当两个线程相互等待对方释放“锁”时就会发生死锁 出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续 多线程编程时应该注意避免死锁的发生

练习——线程同步 需求说明: 使用线程同步实现两个用户同时安全操作一个银行账户

生产者和消费者问题 线程间通信 假设仓库中只能存放一件产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走消费 如果仓库中没有产品,则生产者将产品放入仓库,否则停止生产并等待,直到仓库中的产品被消费者取走为止 如果仓库中放有产品,则消费者可以将产品取走消费,否则停止消费并等待,直到仓库中再次放入产品为止

线程的同步与互斥 线程间需协调与通讯:生产者/消费者问题 进队 出队 生产者 消费者

这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件 线程间通信的必要性 这是一个线程同步问题,生产者和消费者共享同一个资源,并且生产者和消费者之间相互依赖,互为条件 对于生产者,没有生产产品之前,要通知消费者等待。而生产了产品之后,又需要马上通知消费者消费 对于消费者,在消费之后,要通知生产者已经消费结束,需要继续生产新产品以供消费 在生产者消费者问题中,仅有synchronized是不够的 synchronized可阻止并发更新同一个共享资源,实现了同步 synchronized不能用来实现不同线程之间的消息传递(通信)

Java提供了3个方法解决线程之间的通信问题 线程间通信的必要性 Java提供了3个方法解决线程之间的通信问题 方法名 作 用 final void wait() 表示线程一直等待,直到其它线程通知 void wait(long timeout) 线程等待指定毫秒参数的时间 final void wait(long timeout,int nanos) 线程等待指定毫秒、微妙的时间 final void notify() 唤醒一个处于等待状态的线程 final void notifyAll() 唤醒同一个对象上所有调用wait()方法的线程,优先级别高的线程优先运行 均是java.lang.Object类的方法 都只能在同步方法或者同步代码块中使用,否则会抛出异常

定义产品类 线程间通信的实现 class SharedData{ private char c; private boolean isProduced = false; // 信号量 public synchronized void putShareChar(char c) { // 如果产品还未消费,则生产者等待 if (isProduced) { try{ System.out.println("消费者还未消费,因此生产者停止生产"); wait(); // 生产者等待 } catch (InterruptedException e) {e.printStackTrace(); } } this.c = c; isProduced = true; // 标记已经生产 notify(); // 通知消费者已经生产,可以消费 System.out.println("生产了产品" + c + " 通知消费者消费..."); public synchronized char getShareChar() { // 如果产品还未生产,则消费者等待 if (!isProduced){ try{ System.out.println("生产者还未生产,因此消费者停止消费"); wait(); // 消费者等待 } catch (InterruptedException e) {e.printStackTrace();} isProduced = false; // 标记已经消费 notify(); // 通知需要生产 System.out.println("消费者消费了产品" + c + " 通知生产者生产..."); return this.c; 线程间通信的实现 定义产品类

定义生产者线程类和消费者线程类 线程间通信的实现 //生产者线程 class Producer extends Thread { private SharedData s; Producer(SharedData s){ this.s = s; } public void run(){ for (char ch = 'A'; ch <= 'D'; ch++){ try{ Thread.sleep((int) (Math.random() * 3000)); } catch (InterruptedException e) { e.printStackTrace(); s.putShareChar(ch); // 将产品放入仓库 //消费者线程 class Consumer extends Thread { private SharedData s; Consumer(SharedData s){ this.s = s; } public void run(){ char ch; do { try { Thread.sleep((int)(Math.random()*3000)); } catch (InterruptedException e) { e.printStackTrace(); ch = s.getShareChar(); // 从仓库中取出产品 } while (ch != 'D');

线程间通信的实现3-3 定义测试类 //测试类 class CommunicationDemo{ public static void main(String[] args){ //共享同一个共享资源 SharedData s = new SharedData(); //消费者线程 new Consumer(s).start(); //生产者线程 new Producer(s).start(); } 演示示例:使用多线程实现生产者消费者问题

Java中实现线程通信的三个方法的作用是什么? 总结 进程和线程有什么联系和区别? 创建线程的两种方式分别是什么? 如何实现线程同步? Java中实现线程通信的三个方法的作用是什么?

2018/12/7 谢谢