第三次作业.

Slides:



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

软件编程基础 一、程序的编辑 Java 源程序是以 Java 为后缀的简单的文本文件,可以用各种 Java 集成开发环境中的源代码编辑器来编写,也可以用其他文 本编辑工具,如 Windows 中的记事本或 DOS 中的 EDIT 软件等。 利用文字编辑器编写下列程序 public class Hello.
阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
3.2 Java的类 Java 类库的概念 语言规则——程序的书写规范 Java语言 类库——已有的有特定功能的Java程序模块
JAVA 编 程 技 术 主编 贾振华 2010年1月.
项目6 通用堆栈.
Java程序设计教程 第一讲 Java概述.
四資二甲 第三週作業 物件導向程式設計.
设计模式可以帮助我们改善系统的设计,增强 系统的健壮性、可扩展性,为以后铺平道路。
第二章 JAVA语言基础.
第10讲 Java面向对象编程基础(4) 教学目标 主要内容.
第三章 控制结构.
Using C++ The Weird Way Something about c++11 & OOP tricks
Ch08 巢狀類別 物件導向程式設計(II).
2.1 基本資料型別 2.2 變數 2.3 運算式與運算子 2.4 輸出與輸入資料 2.5 資料型別轉換 2.6 實例
Java语言程序设计 第七部分 多线程.
Java基础 JavaSE异常.
Classes Lecturer: 曾學文.
程序與函數的類別方法 目的:模組化程式設計 方法:由上而下設計 注意事項:(1)獨立性 (2)結合問題 (3)子問題間的溝通.
程式敘述執行順序的轉移 控制與重複、方法 Lecturer:曾學文.
第3章 語法入門 第一個Java程式 文字模式下與程式互動 資料、運算 流程控制.
本單元介紹何謂變數,及說明變數的宣告方式。
西南科技大学网络教育系列课程 高级语程序设计(Java) 第五章 继承、接口与范型.
Ch10 類別與物件-方法 Java程式設計(2).
程式設計實作.
2018/12/3 面向对象与多线程综合实验-网络编程 教师:段鹏飞.
Java语言程序设计 第五部分 Java异常处理.
辅导课程六.
临界区软件互斥软件实现算法.
并发机制 结果应该为: 线程 1: 1 线程 1: 2 线程 1: 3 线程 1: 4 线程 1: 5 线程 2: 6 线程 2: 7
第一单元 初识C程序与C程序开发平台搭建 ---观其大略
第一次课后作业 1. C/C++/Java 哪些值不是头等程序对象 2. C/C++/Java 哪些机制采用的是动态束定
9.1 程式偵錯 9.2 捕捉例外 9.3 自行拋出例外 9.4 自定例外類別 9.5 多執行緒
3.1 数据类型 3.2 标识符与关键字 3.3 常量 3.4 变量 3.5 运算符与表达式 3.6 一个编程实例
异常及处理.
临界区软件互斥软件实现算法 主讲教师:夏莹杰
認識 Java.
C/C++/Java 哪些值不是头等程序对象
4.2通讯服务模块线程之间传递信息 信息工程系 向模军 Tel: QQ:
简单工厂模式.
Multithread 多執行緒 以GUI為例了解物件以及Event
辅导课程八.
JAVA 编 程 技 术 主编 贾振华 2010年1月.
《JAVA程序设计》 语音答疑 辅导老师:高旻.
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则
简单介绍 用C++实现简单的模板数据结构 ArrayList(数组, 类似std::vector)
$9 泛型基础.
第7章 异常处理.
Aspect Oriented Programming
第二章 Java基本语法 讲师:复凡.
Java程式初體驗大綱 大綱 在學程式之前及本書常用名詞解釋 Hello Java!程式 在Dos下編譯、執行程式
信号量(Semaphore).
本节内容 类成员的访问控制 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
第二章 Java语法基础.
Chapter 18 使用GRASP的对象设计示例.
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
第二章 Java基本语法 讲师:复凡.
临界区问题的硬件指令解决方案 (Synchronization Hardware)
第6單元 6-1 類別的繼承 (Class Inheritance) 6-2 抽象類別 (Abstract Class)
C++语言程序设计 C++语言程序设计 第九章 类的特殊成员 第十一组 C++语言程序设计.
JAVA 程式設計與資料結構 第三章 物件的設計.
第2章 Java语言基础.
判斷(選擇性敘述) if if else else if 條件運算子.
使用Fragment 本讲大纲: 1、创建Fragment 2、在Activity中添加Fragment
第二章 Java基础语法 北京传智播客教育
輸出執行結果到螢幕上 如果要將執行結果的文字和數值都「輸出」到電腦螢幕時,程式要怎麼寫? class 類別名稱 {
第二章 Java基本语法 讲师:复凡.
第6章 继承和多态 伍孝金
Summary
Presentation transcript:

第三次作业

第一题-问题描述 结果应该为: 线程 1: 1 线程 1: 2 线程 1: 3 线程 1: 4 线程 1: 5 线程 2: 6 线程 2: 7 线程 2: 8 线程 2: 9 线程 2: 10 ... 线程 3: 71 线程 3: 72 线程 3: 73 线程 3: 74 线程 3: 75 启动 3 个线程打印递增的数字, 线程 1 先打印 1,2,3,4,5, 然后是线程2 打印 6,7,8,9,10, 然后是 线程 3 打印 11,12,13,14,15。 接着再由线程 1 打印 16,17,18,19,20....以此类推, 直到打印到 75。 程序的输出如右方所示。 请用多种方法(synchronized、Lock 等)控制 线程,实现输出打印。 给出源代码(对关键代码进行说明)、编译 环境以及执行时间。 总结保证线程安全、同步的方法。 基本所有同学都能给出2-3种实现方法,并给出代码、编译环境和打印结果。

第一题-实现方法1 通过全局变量或标志位来 指定当前由哪一个线程打 印数据。 class OrderPrint extends Thread { private static int who = 1; // whose turn to print private static int number = 1; // number to print private int limit; // how many numbers I can print private int count; // how many numbers printed so far private int me; // self id number public OrderPrint(int total, int id) { limit = total; me = id; count = 0; } // indicates which thread to print numbers public int whoseTurn() { return who; } // set next thread to run public void setWho(int turn) { who = turn; } public void run() { while (true) { if (whoseTurn() == me) { // my turn to print numbers for (int i = 0; i < 5; i++) { System.out.println("线程" + me + ": " + number); count++; number++; } setWho(me+1 > 3 ? 1 : me+1); // set who to next one to print if (count >= limit) // enough number have been printed return ; public static void main(String[] args) { // each thread prints total of 75/3 numbers new OrderPrint(75/3, 1).start(); new OrderPrint(75/3, 2).start(); new OrderPrint(75/3, 3).start(); 通过全局变量或标志位来 指定当前由哪一个线程打 印数据。 简单清晰,不会发生资源 竞争(同一时间只有一个 线程修改变量值,其他线 程只是读取变量值)。 代码来自:SY1306230_余恒洋 代码来自:SY1306230_余恒洋

第一题-实现方法2 采用原始的synchronized, wait(), notify(), notifyAll()等方式控制线程。 特点 利用synchronized实现互斥变量的保护,如果互斥变量当前的标号不 等于线程的ID号就让他等待,否则进入访问区域,访问之后对互斥变 量的计数进行更新,以便下一个线程可以访问互斥变量,并通知所有 等待的线程互斥变量空闲。 特点 synchronized是在JVM层面实现的,不但可以通过一些监控工具监控 synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放 锁定。 在资源竞争不是很激烈的情况下,偶尔会有同步的情形下, synchronized很合适。因为编译程序通常会尽可能的进行优化 synchronize,另外可读性非常好。 基本所有同学都能给出2-3种实现方法,并给出代码、编译环境和打印结果。

第一题-实现方法2 采用原始的synchronized, wait(), notify(), notifyAll() 等方式控制线程。 基本所有同学都能给出2-3种实现方法,并给出代码、编译环境和打印结果。

第一题-实现方法3 采用JDK并发包提供的Lock, Condition等类的相关方 法控制线程。 特点 每次一个线程执行完五个打印任务时,指定将要唤醒 的下一个进程,而不是唤醒所有进程。 特点 lock是通过代码实现的,要保证锁定一定会被释放,就 必须将unLock()放到finally{}中 在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock(如本题),但是在资源竞争很激烈的情况下则相反 Java线程同步的其他方法:volatile,CountDownLatch,CyclicBarrier,DelayQueue,PriorityBlockingQueue,ScheduledExecutor,Semaphore,Exchanger

效率对比 1 安全性 synchronized是在JVM层面上实现的,不但可以通过一些监控工具监控synchronized的锁定,而且在代码执行时出现异常,JVM会自动释放锁定,但是使用Lock则不行,lock是通过代码实现的,要保证锁定一定会被释放,就必须将unLock()放到finally{}中。 2 效率 在资源竞争不是很激烈的情况下,Synchronized的性能要优于ReetrantLock(如本题),但是在资源竞争很激烈的情况下则相反。

第一题-线程安全/同步总结1 保证线程安全的三种方法: 实现同步机制的方法: 不要跨线程访问共享变量; 使共享变量是final类型的; 将共享变量的操作加上同步。 实现同步机制的方法: 同步代码块 synchronized(同一个数据){} 同一个数据:就是N条线程同时访问一个数据。 同步方法 public synchronized 数据返回类型 方法名(){} 在资源竞争不是很激烈的情况下,偶尔会有同步的情形下,synchronized很合适。因为编译程序通常会尽可能的进行优化synchronize,另外可读性非常好。

第一题-线程安全/同步总结2 通过使用同步方法,可非常方便的将某类变成线程安全的类,线程安全特征如下: 该类的对象可以被多个线程安全的访问。 每个线程调用该对象的任意方法之后,都将得到正确的结果。 每个线程调用该对象的任意方法之后,该对象状态依然保持合理状态。 注意:不要对线程安全类的所有方法都进行同步,只对那些会改变共享资源方法的进行同步。 基本所有同学都能给出2-3种实现方法,并给出代码、编译环境和打印结果。

对于同步方法而言,无需显示指定同步监视器,同步方法的同步监视器是 this 也就是该对象的本身(这里指的对象本身有点含糊,其实就是调用该同步方法的对象)。

2、对于一个账户类Account,有以下定义 class Account { int balance; synchronized void deposit(float amt) {//存款 balance += amt; } synchronized void withdraw(float amt) {//取款 if(balance < amt) throw new OutOfMoneyError(); balance -= amt; 如果在Account中添加以下方法 void transfer(AccountJ other, float amt) { other.withdraw(amt); this.deposit(amt); 试分析,调用该transfer方法时会出现什么问题,如果为该方法添加关键字 synchronized,调用时是否还有问题?

调用transfer方法会造成资源竞争,导致balance的和不一致。因为多个线程之间的other. withdraw(amt)和this 调用transfer方法会造成资源竞争,导致balance的和不一致。因为多个线程之间的other.withdraw(amt)和this.deposit(amt)操作顺序无法保证。 当为transfer()方法添加关键字synchronized后,会产生嵌套synchronized导致死锁。

面向对象编程与基于对象编程 根据javascript的基于对象编程思想实现以下功能并进行比较说明它们的实现机制的异同: public class ClassA { public int a = 1; public static int b = 2; public int c() { return 3; } ClassA obj = new ClassA(); System.out.println(obj.a); //输出:1 System.out.println(obj.b); //输出:2 System.out.println(obj.c()); //输出:3

function ClassA() { this.a = 1; //调用this指针 this.c = function() { return 3; }; } ClassA.b = 2; //定义“类变量”(本质是函数的变量),不能通过用new产生的实例调用类属性 var obj = new ClassA(); console.log(obj.a); //输出:1 console.log(ClassA.b); //输出:2 console.log(obj.c()); //输出:3

由于JavaScript是一种基于对象(object-based)的语言而不是严格意义上的面向对象(object-oriented)语言,在进行编程时则与Java有很大区别。 1.实例属性(变量)的定义与使用 Java: public class ClassA { public int a = 1; } ClassA obj = new ClassA(); System.out.println(obj.a); //输出:1   JavaScript: function ClassA() { this.a = 1; //第一种:调用this指针 }; ClassA.prototype.b = 2; //第二种:调用prototype(对象原型) var obj = new ClassA(); console.log(obj.a); //输出:1 console.log(obj.b); //输出:2 JavaScript中对象的属性定义有两种方法,其中调用this指针的方法与Java最为相似。

2.实例方法(函数)的定义与调用 Java: public class ClassA { public int c() { return 3; } ClassA obj = new ClassA(); System.out.println(obj.c()); //输出:3   JavaScript: function ClassA() { this.c = function() { }; var obj = new ClassA(); console.log(obj.a()); //输出:1; console.log(obj.b()); //输出:2; 方法和属性的定义、使用是非常相似的,没有太多变化。

3.类属性(静态属性)的定义与调用 Java: public class ClassA { public static int A = 1; } System.out.println(ClassA.A); //直接调用类,输出:1 ClassA obj = new ClassA(); System.out.println(obj.A); //调用由类产生的实例,输出:1   JavaScript: function ClassA() { } //首先初始化对象 ClassA.A = 1; //定义“类变量”(本质是函数的变量) console.log(Class.A); //直接调用类,输出:1 var obj = new ClassA(); console.log(obj.A); // 错误!不能通过用new产生的实例调用类属性 在Java中,可以类的实例调用静态属性,但JavaScript中不允许这样做,这和JavaScript中使用函数表示对象的设计有关。