Core java for impatient 笔记
类比c++来学习!
1.在java 中变量不持有对象,变量持有的是对象的引用,可以把变量看做c++中的只能指针,自动管理内存
需要手动初始化(否则就是空指针!)
2.final 相当于c++中的const
java中的嵌套类:
1.静态嵌套类:
类可以获取静态嵌套类中变量和方法的使用权
2.内部类
内部类的方法可以访问它的外部类的实例变量。在这种情况下,它们是外部类的实例变量!
静态嵌套类和内部类的不同之处在与每个内部类对象都有自己外部类对象的引用。
在调用外部类方法的时候实际调用的是 outer.f()
解释内部类的外部类引用的时候,将其称为outer
接口是一种特殊的类,可以可做java对于行为的抽象!接口的默认定义是static和final的变量,可以有默认的实现方法!
继承接口的类必须实现接口的方法!并且将接口的方法声明为public!
在接口的默认方法和父类的方法发生冲突对的时候优先选择父类方法
java中常用的接口
Comparable接口
Comparator接口
Runnable接口,产生一个没有返回值的函数
lambda表达式是一块代码,可以将这一部分作为定义的方法或者对象传递出去。
lambda表达式方法中的this代表的是创建lambda表达式的方法的this参数
经常需要在lambda中访问来自闭合方法或者类的变量:
当lambda定义的行为在线程中调用的时候,引用的变量可能已经不存在了。。。怎么办?
lambda表达式有三个部分:1.代码块2.参数3.自由变量的值(既不是参数变量也不是内部定义的变量)
lambda的表达式必须在数据结构中存储这些值!
就是说这些值已经被lambda表达式捕获了(为了确保被捕获的值是良好定义的,在lambda中你只能引用那些值不会改变的变量,final变量)
可以定义局部类然后返回构造函数,相当于实现简单工厂设计模式。。
子类可以使用关键字super来调用父类的方法或者构造函数。
final方法不能被覆盖,final类不能被继承!
.
java中所有类都是object的子类,提供了toString,hash,Clone,equals等方法。
class加载了java类型的信息,包括类,数组,接口,基本类型
反射库可以让程序在运行过程中访问类的成员,变量和方法!
在向下转换的时候,安全的方法是使用instanceof检测,然后再用强制类型转换方法转换!
抽象方法和类:对某一个对象的特定行为的抽象和对某一类对象的抽象!
当你在子类中定义equals方法的时候首先要调用父类的equals方法,因为当父类的检查都没有通过的时候,对象必定不相等!
自带的clone()在处理引用的引用时是浅拷贝,如果需要深拷贝自己定义。
在处理静态成员的时候要当选新他们的构造次序,由于枚举常量在静态成员之前构建,所以你不能再构造函数里引用任何静态成员。
java种的泛型编程:
在任何包含泛型编程的编程语言中,当你限制或者改变参数类型常常会有些棘手,泛型类是带有一个或者多个类型参数的类,泛型方法是带有类型参数的方法,在泛型编程中可以做出明确要求:要求对象的类型是某一个或者多个雷星星对的子类型(使用通配符 G<? extends T> 或者 G<? super T>来指定)
当你声明一个泛型方法的时候,类型参数要放在修饰符之后,返回类型之前,调用泛型方法的时候可以把类型参数放在函数名称之前,得到一个更好的错误信息!
可以对泛型的类型做出明确的限定,要求继承某些类或者实现某些接口!
对于数组的参数传递要求:
可以传递一个子类的数组,但是ArrayList<子类>不是ArrayList<父类>的子类型,存在这种限制的原因是,如果把ArrayList<Manager>赋给父类list是合法的,那么可能存在子类的列表中混杂了父类的元素(ArrayList的add方法允许添加父类哦!),但是数组是不允许这种操作滴!(因为它不能动态添加元素啊!)
然而在一些时候我们可以确定这样的类型转换不会困扰我们,此时我们可以用子类型通配符或者副类型通配符!
java虚拟机中的反省有一些限制,因为在实现的时候采用了类型擦除,当你定义了一个泛型类型的时候,它会被编译成为一个原始类型Object!所以我们在使用的时候有一些限制,无基本类型参数,因为他们不是Object的子类!所有类在运行期间都是原始的,你不能检测一个元素是否是一个类的对象!不能用泛型名称实例化变量,但是可以使用反射机制得到构造器方法!
类型擦除是在编译器检测合法类型转换的前提下安全实现的。
JAVA中的数据结构(感觉没有C++的STL强啊、、、、可能是我还没领悟到精髓吧!)
Collection 接口为所有的集合类提供了共同方法!(除了映射!)
列表是一个有序集合,其中的每个元素都有一个整数索引!
对映射来说,你可以选择HashMap和TreeMap
视图通过使用标准集合接口体用了对存储在其他地方的数据的访问方式!
集合视图是一个实现了集合接口的轻量级对象,不存储元素。。
并发编程(重点!)
本章要点:
1.Runnable 表述一个可以异步执行的任务
2.Executor 将Runnable 实例列入执行任务
3.Callable 描述一个会产生结果的任务
4.你可以向ExecutorService 中提交一个或者多个Callable实例,并且当这些Callbale执行结果后,合并这些结果。
5.当多个线程在没有同步的情况下操作共享数据时,其结果不安全!
6.使用并行算法和线程安全的数据结构 优于 使用锁机制编程
7.并行Stream和数组操作可以自动并且安全地将计算并行化运行。
8.ConcurrentHashMap是线程安全的hash表,允许院子更新其中的元素
9.确保一个时刻只有一个线程执行临界区
10.当设置了终端标志或者InterruptException异常发生时,可中断任务应该终止
并发任务。
Runnable接口实现run()
Executor有一个工厂方法提供不同类型的executor的调用。
Exector exec = .....;
exec.excute(task);
而exec.newCachedThreadPool();会产生一个有很多短暂任务或者任务会消耗很多时间等待的程序优化过的executor。如果可能的话,每个任务在空闲的线程上执行。
exec.newFixedThreadPool(nthreads)会产生一个数目固定的线程池,当你提交任务的时候,进行排队直到有可用的 线程。对计算密集型任务,这是个不错的选择!(不懂。。啥叫计算密集型任务?知乎答案:程序系统大部分在做计算、逻辑判断、循环导致cpu占用率很高的情况,称之为计算密集型;频繁网络传输、读取硬盘及其他io设备称之为io密集型)
Future 和Executor服务
一个计算划分为多个子任务,所有任务完成后合并结果,Callable接口的call方法可以返回值!
要执行Callable,你需要一个ExecutoService接口的实例,前面说的两个POOL!
Future<V> result = exec.submit(task);
futrure表示计算的对象,将来的某个时候会有可用的计算结果。
有一下接口
get方法会产生阻塞知道有了可用的结果!
cancel方法视图取消任务,如果任务没有被执行就不会加入计划,否则中断当前运行任务的线程!
也可以加入一个List座位executor的invokeAll参数
当任务完成你得到一个List<V>的future
invokeAny只要有一个任务完成了并且没有返回异常那么就把当前的值返回。。
线程安全:
1。可见性
在一个线程中修改的布尔值可能不会被另一个线程看见,原因是变量在线程中被读取出来并不会存储到内存中。。
有几种方式确保对变量对的更新是可见的:
1.final 变量的值在初始化后是可见的。
2.static变量的初始值在静态初始化后是可见的。
3.对volatile变量的改变是可见的。
4.发生在锁被释放之前对试图获取同一个锁的任何人是可见的。
10.2竞争条件
当多个并发任务同时更新一个共享整数计数器:
即使变量是volatile的,有可能因为线程抢占的,因为把变量存储到内存的时机不同,导致数据被损坏。
安全并发的策略:
1.限制:拒绝在任务中间共享数据。
2.不变性:如果一定要共享,我们让他是final的。
3.锁:通过授权一次只有一个任务访问数据结构。
不可变类(如果一个类一旦构造完毕,就不能改变了,那么这个类是不可变的)
Java中提供的并行运算:
1.并行流:自动将大型并行流上的操作并行化。
2.并行数组操作:Arrays.parrallelSort等等
线程安全的数据结构
ConcurrentHashMap
安全更新一个值用compute函数通过一个Key和一个计算新值的函数来调用compute方法,函数接收Key和关联的值,如果没有值就为NULL。是原子的!
merge方法修改旧值
阻塞队列是在任务之间协调工作的一个常用工具:当你试图向一个满的队列中添加元素,或者从一个空队列中取值的时候操作就会被阻塞。
原子值:如果多个线程更新一个共享计数器,确保更新操作是线程安全的方式进行的。
锁:如何构造线程安全的计数器或者阻塞队列:
ReentrantLock
为避免损毁共享变量,需要确保每次只有一个线程可以计算并且设置新值。可以使用锁来实现临界区。
countLock.lock();
try
{
count++;//临界区
}
finally
{
countLock.unlock();
}
第一线程实行lock方法,锁住对象,进入临界区,如果另一个线程试图调用lock方法,它会被阻塞!
这样可以确保每次只有一个线程执行临界区。
注意:unlock方法通常放在finally中,如果临界区中发生异常,那么锁一定会被释放,否则锁将永远被锁住,其他线程因为无法获得锁二无法处理!如果在编程中不加小心很可能造成死锁。
Core java for impatient 笔记的更多相关文章
- Core java for impatient 笔记 ch8 流
流stream 使用了数据视图,让你可以在比集合更高的概念上指定操作使用流,你只需要将操作的调度留给实现,例如,假设你要计算某个属性的平均值,你只需要指定数据源和属性,然后流类库会优化计算,比如使用多 ...
- Core Java 学习笔记——1.术语/环境配置/Eclipse汉化字体快捷键/API文档
今天起开始学习Java,学习用书为Core Java.之前有过C的经验.准备把自己学习这一本书时的各种想法,不易理解的,重要的都记录下来.希望以后回顾起来能温故知新吧.也希望自己能够坚持把自己学习这本 ...
- Core Java读书笔记之String
Java里面的String Conceptually, Java Strings are sequences of Unicode characters. Java里面的String都是Unicode ...
- java多线程学习笔记——详细
一.线程类 1.新建状态(New):新创建了一个线程对象. 2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...
- Android(java)学习笔记160:Framework运行环境之 Android进程产生过程
1.前面Android(java)学习笔记159提到Dalvik虚拟机启动初始化过程,就下来就是启动zygote进程: zygote进程是所有APK应用进程的父进程:每当执行一个Android应用程序 ...
- Core Java (十一) Java 继承,类,超类和子类
Core Java (十一) Java 继承,类,超类和子类 标签: javaJavaJAVA 2013-01-22 17:08 1274人阅读 评论(0) 收藏 举报 分类: java(58) 读 ...
- Android(java)学习笔记103:Framework运行环境之 Android进程产生过程
1. 前面Android(java)学习笔记159提到Dalvik虚拟机启动初始化过程,就下来就是启动zygote进程: zygote进程是所有APK应用进程的父进程:每当执行一个Android应用程 ...
- Java Web学习笔记之---EL和JSTL
Java Web学习笔记之---EL和JSTL (一)EL (1)EL作用 Expression Language(表达式语言),目的是代替JSP页面中复杂的代码 (2)EL表达式 ${变量名} ( ...
- Java:并发笔记-06
Java:并发笔记-06 说明:这是看了 bilibili 上 黑马程序员 的课程 java并发编程 后做的笔记 5. 共享模型之无锁 本章内容 CAS 与 volatile 原子整数 原子引用 原子 ...
随机推荐
- js拿到焦点所在的标签对象
通过 document.activeElement 此时是js对象,如果要调用jQuery的API那么就转换成jquery对象 $(document.activeElement)
- 深入理解java虚拟机---垃圾收集器和分配策略-1
博文重点: 学习目标:哪些内存需要回收 什么时候回收 如何回收 在基于概念讨论的模型中,主要对Java堆和方法区进行讨论. why?:一个接口中的多个实现类需要的内存可能不一样,一个方法中的多个 ...
- 利用ObjectMapper readValue()和泛型解决复杂json结构
import com.dj.fss.vo.MessageListVO; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; im ...
- BEGIN - 开始一个事务块
SYNOPSIS BEGIN [ WORK | TRANSACTION ] DESCRIPTION 描述 BEGIN 初始化一个事务块, 也就是说所有 BEGIN 命令后的用户语句都将在一个事务里面执 ...
- Android网站
http://blog.csdn.net/airsaid/article/details/52902299 android调用传感器的代码 http://blog.csdn.net/huangbiao ...
- No-1.第一个 Python 程序
1. 第一个 HelloWorld 程序 1.1 Python 源程序的基本概念 Python 源程序就是一个特殊格式的文本文件,可以使用任意文本编辑软件做 Python 的开发 Python 程序的 ...
- myeclipse出现Failed to load JavaHL Library.
eclipse启动出现如图的状况: 解决方法: Window-Preferences-Team-SVN,在SVN接口的下拉框可以看到,默认选择的是JavaHL(JNI) Not Available,手 ...
- 【Pytorch】关于torch.matmul和torch.bmm的输出tensor数值不一致问题
发现 对于torch.matmul和torch.bmm,都能实现对于batch的矩阵乘法: a = torch.rand((2,3,10))b = torch.rand((2,2,10))### ma ...
- formatDate() 格式化日期
function datefmt(milSec, format) { var oldTime = Number(milSec); //得到毫秒数 // 日期格式转换 var t = new Date( ...
- java枚举中常见的7中用法
2016年08月11日 11:14:45 李学凯 原文链接https://blog.csdn.net/qq_27093465/article/details/52180865 JDK1.5引入了新的 ...