-
策略模式(接口的使用,用来理解Runnable接口)
策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换策略模式让算法独立于使用它的客户而独立变化。
设计原则是把一个类中经常改变或者将来可能改变的部分提取出来,作为一个接口,然后在类中包含这个对象的实例,这样类的实例在运行时就可以随意调用实现了这个接口的类的行为。
-
策略模式的组成
抽象策略角色: 策略类,通常由一个接口或者抽象类实现。
具体策略角色:包装了相关的算法和行为。
环境角色:持有一个策略类的引用,最终给客户端调用。
-
实现
-
课后作业:动手实现策略模式,并查看相关文档,看一下策略模式的优缺点
-
泛型初步
-
泛型基本概念
主要是引入了类型参数这个概念,允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。
-
实例
-
泛型的注意点:课后作业
-
异常初步
Java中异常提供了一种识别及响应错误情况的一致性机制,有效地异常处理能使程序更加健壮、易于调试。异常之所以是一种强大的调试手段,在于其回答了以下三个问题:
•什么出了错?
•在哪出的错?
•为什么出错?
-
异常分类
-
Checked Exception(非Runtime Exception):必须处理,捕获或者抛出
-
Unchecked Exception(Runtime Exception):一般不做try catch处理
-
异常的处理结构
见代码
-
自定义异常
见代码
-
注解初步
-
解释:annotation,可以用在成员,方法,类等等前面,用来给编译器提供信息
-
Jdk提供的注解:override,deprecated
-
自定义注解
-
反射基础
反射在运行时获取类的属性和方法,这种机制是动态语言的一个属性,动态语言如JavaScript。这类语言在运行时,可以改变变量的数据类型。
Java不是动态语言,但是Reflection是动态机制,利用这种机制可以加载一个运行时才可以知道名称的class并获得其成员定义。
反射相当于从JVM的角度去获取对象所属的类的信息。
-
java反射机制提供的主要功能:
-
运行时判断一个对象所属的类
-
运行时构造任意一个对象的类
-
运行时判断一个类所具有的成员变量和方法
-
运行时调用任意对象的方法
-
反射的API
反射的API位于java.lang.reflect包下,相关的类如下:
-
Class类:在java.lang包下,包含了一个类的信息,每个类仅有一个
-
Field类:存放类的成员信息
-
Method类:代表类的方法
-
Constractor类:代表构造方法
-
Array类:动态创建对应类的数组
-
调用反射机制的过程
-
获取Class对象,forName(String),类.class,对象.getClass()
-
通过Class对象,构建Class对象对应的类的对象
-
通过Class对象获取类的成员和方法(包括构造方法)
-
对类进行操作
-
实例:
-
利用反射,获取String类的所有方法
-
利用反射,调用自定义类的方法并执行:getMethod(),newInstance(),invoke()
-
利用反射,复制一个对象:Constractor类,newInstance()
-
利用反射,调用对象的private方法和修改private成员
-
利用反射,创建对象数组Array.newInstance(Class<?> classtype,int length())
-
作业:创建一个类的数组,并复制该数组,其中get/set方法用标准命名方式,利用反射实现
-
线程基础
Java内置支持多线程,多任务处理。
-
进程和线程
进程和线程都是动态的概念。
进程是运行中的程序,多个进程的内部数据和状态完全独立,多个线程共享内存和系统资源,一个进程可以包含多个线程。进程的本质就是执行的程序,允许计算机同时执行多个任务,如同事打开浏览器和文本编辑器。
线程本身不能运行,只能用于程序当中。在基于多线程的任务系统中,一个程序可以执行多个任务,如在浏览器中,打开两个界面,或者进行两个下载任务。
进程与线程的关系,可以用搬砖的例子来说明。
多线程的最终目的就是充分利用cpu和提交并发的效率。在网络环境中,读取网络文件的速度<本地文件读取速度<处理器处理速度。如果没有多线程技术,则必须顺序执行,如果网络不能响应,则需要等待该任务的完成才能进入下一个任务。
-
线程的生命周期
-
创建状态
-
可运行状态
-
不可运行状态
-
消亡状态
-
线程的实现
线程的一些基本概念:
-
Thread类:位于java.lang.Thread,继承Object类
-
每个线程有优先级,高优先级的先执行
-
新创建的线程的优先级等于创建它的线程的优先级
-
每个线程都有名字,名字有可能重名,但id不会重复
创建线程的两种方式:
-
继承Thread类,然后重写run()方法
-
继承Runnable接口
注意:线程的启动要执行线程对象的start()方法;实际上Thread类也是通过实现Runnable接口来实现线程的。Runnable接口被作为参数传入,尽管线程执行的内容不同,但是这种机制类似于策略模式。
-
线程的优先级
-
新建的线程的优先级与创建它的线程优先级相同
-
设置线程优先级的方法:setPriority,线程的优先级1-10,10最高
-
线程的优先级设置好以后,系统在执行过程中仍然会进行调整
-
线程的调度策略
-
优先选择优先级高的
-
线程体内部调用yield(),让出cpu
-
sleep()方法进入睡眠
-
i/o阻塞
-
更高优先级到
-
线程的同步
-
资源锁(需要大家回去动手实践)
多线程下,synchronized关键字的一些注意点:
-
各线程对同一个成员变量的操作,彼此影响:例如对set方法加上synchronized后,其他线程不能使用该方法,除非解锁或者异常
-
如果对一个对象有多个synchronized所上的方法,则在一个线程访问其中一个synchronized方法时,其他线程不能访问其他的synchronized方法
-
如果对象被synchronized的方法是static的,那么,synchronized是针对该对象对应的类的Class对象,此时也是顺序的
-
局部变量的改变不影响其他线程
-
synchronized(object):多个线程访问同一个对象
-
synchronized代码块
-
-
线程之间的同步通信
-
Wait/notify
-
哲学家就餐的问题(作业)
-
-
其他
-
isAlive()
-
getPriority()
-
setPriority()
-
sleep()
-
yield()