以下内容,是我根据自己的理解,对Java知识进行总结,如有不足,希望大神多多指正。
1.java虚拟机
内存包括内存共享区和内存私有区,共享区包括堆和方法区,私有区包括虚拟机栈、局部变量表、本地方法区,除了这些一些虚拟机还包括直接内存,通过NIO技术可以操作。
堆:中包括几乎所有对象和数组,虚拟机优化之后,一些对象会在栈上执行,是因为逃逸技术。
方法区:包括final、static、编译后的class。
虚拟机栈:包括局部变量表、操作数栈、返回地址、动态链接、本地线程缓存等,进行对象引用的入栈出栈操作,局部变量表中存放一些基本数据类型和局部变量的引用。
本地方法栈:存放native的方法
程序计数器:为当前线程进行标识,为什么需要程序计数器?因为需要线程切换
为什么jvm要使用栈,先进后出,符合方法间的调用
2.垃圾回收机制
垃圾回收主要是堆和方法区,按照GC Root引用链,回收引用的对象,包括栈中引用、本地方法区引用、final、static引用的对象。其中方法区回收效率差,只回收无用final和无用类。
引用分为:
强引用,new对象,只要存在就不会回收,只有当引用为null时,才会回收
软引用,在内存溢出OOM时进行回收
弱引用,下一次垃圾回收gc时候回收
虚引用,在回收时候进行一些操作,收到一个系统通知
另外,没有引用,内存满了必然回收
分为新生代、老年代、永久带(方法区)
gc算法一般分为copy算法、mark算法、分代收集算法
copy算法使用一个大的Eden空间和两个小的survivor空间,将存活的对象,先复制到Eden和一个survivor里,不够再使用survivor,再不够使用老年代,始终保证一个survivor为空闲。
Mark算法标记存活的进行回收
3.多线程并发
CPU核心数即通常说的双核、四核、八核,线程数一般与核心数为2:1的关心,源于后来Intel提出的超线程技术。
而我们通常开发时用到的线程是通过时间片轮转机制,将线程分为一个个时间片实现并发的。
进程是操作系统分配的资源,包括CPU、内存空间、磁盘IO等,一个进程对应多个线程,线程的并行是真正的同时执行,而并发需要在一段时间内运行,需要有时间的概念。
线程在使用时候还需要注意线程安全的问题,和synchronized同步有关。以及线程调用时候注意死锁问题。
Java中只有Tread具有线程的概念
线程启动的方式有三种:
1、x extends Thread;然后运行x.run();然后调用start();
2、x implements Runnable;实现run方法,然后new Thread(run).start();
3、x implements Callable;实现call方法,然后new FutureTask<>(call);然后new Thread(run).start();
其中FutureTask实现了Future和Runnable接口。
线程的中止:有一些过期的API提供了stop(),stop()不保证线程的资源是否正常释放,所以被废弃了;常用的中止方法为interrupt,在这里就体现了线程是协作式的,而不是抢占式的。interrupt配合isInterrupted()或Thread.interrupted()来使用,原理是通过设置Boolean标志位实现。
线程的yield()方法:让出当前线程的CPU占有权,但让出时间不确定。
线程的join方法:把指定的线程加入到当前线程,意思是把两个线程顺序执行,如在B中A.join(),会先执行A,再执行B.
线程同步实现:synchronized内置锁机制,其实是对象锁和类锁的概念,通过锁定类、方法、代码块实现线程锁定以及同步。还有显示锁Lock,显示锁是一个接口,通过ReentrantLock实现,内置锁不可以配置,显示锁可以实现一些其他功能,如中断锁、超时获取锁、非阻塞获取锁等。还包括读写锁的方法。非公平锁比公平锁性能更优。通过condition实现了类似wait方法的功能。
线程协作,即生产消费者模式,由于线程难以及时响应,所以难以有效的协作。通过wait()/notifyAll()有效的实现了线程间的协作,并且在使用时都要有synchronized内置锁控制。
线程隔离,即ThreadLocal,它是键值对结构,以ThreadLocal为键,包括initialValue、get、set、remove等方法。
handler机制的Looper对象就是通过ThreadLocal实现的。
线程池Threadpool:好处实现线程的复用,降低消耗、提高响应速度
线程池七个主要参数:
corePoolSize:线程池线程核心数
maximumPoolSize:线程池中运行最大线程数
keepAliveTime:线程没有任务运行时,继续存活的时间
TimeUnit:keepAliveTime时间单位
workQueue:BlockingQueue阻塞队列,满了阻塞的意思
threadFactory:线程工厂,线程命名时用到
RejectedExecutionHandler:饱和策略,当线程池满了,执行一些方法,如抛出异常、执行任务、丢弃任务
工作机制:当线程小于corePoolSize,新建线程,若线程多于corePoolSize,加到阻塞队列里,若阻塞队列满了,新建线程,若新建的线程超过maximumPoolSize,则调用RejectedExecutionHandler.rejectedExecution()方法。
cpu密集型设置cpu+1,IO密集型设置2×cpu,混合型视情况而定。
AsyncTask原理:创建时通过创建线程池和串行化任务,执行时从队列中轮询,消息处理通过handler实现
缺点:不适合大量UI异步更新,需要考虑多线程的控制问题。
static:执行时不依附于任何对象,先于类中其他对象执行,可以通过this来调用,如this.static对象
4.设计模式
创建型:
1.单例模式:
优选方案:饿汉式、静态内部类、双重加锁dcl需加volatile关键字
2.建造者模式:
用户不关心产品是如何创建的,直接调用
应用场景:AlertDialog.builder
3.工厂方法模式:
每一个产品对应每一个工厂
4.简单工厂模式:
实现了接口的简单封装,一个工厂生产很多产品
5.抽象工厂模式:
抽象工厂可以理解成:一个工厂里可以生产多个产品
6.原型模式:
调用clone方法实现对象的拷贝
浅拷贝:直接将对象引用拷贝给新对象
深拷贝:先复制一个对象,然后将新对象进行浅拷贝
应用场景:Intent中实现了Cloneable接口,但却用new实现的
结构性模式
7.代理模式:
一个真实对象接口,一个真实对象,一个代理对象,代理对象持有真实对象的引用
动态代理:一个真实对象接口,一个真实对象,一个动态代理类,实现了InvocationHandler方法,重写它的invoke(),内部用反射实现
应用场景:ActivityManager中的ActivityManagerProxy
8.组合模式:部分—整体模式
透明的组合模式:抽象类里包含所有抽象方法
安全的组合模式:抽象类里包含基本方法,一些其他方法在子类实现
应用场景:ViewGroup与View,并且是安全的组合模式
9.适配器模式:
对象适配器:适配器中持有源对象的引用
类适配器:继承源对象,实现adapter接口,不需要持有源对象引用
应用场景:RecyclerView属于类适配器
10.装饰者模式:
扩展一个类的额外功能时,是继承的替代方案之一
应用场景:Context类,Context是具体抽象类,ContextImpl具体实现类,ContextWrapper是装饰角色,Activity、Service是扩展的功能
11、桥接模式:
如果两端都需要拓展,可以用桥接模式,比如,人穿衣服,衣服有多种,人有多种,可以进行拓展(人中需要持有衣服的引用)
应用场景:window与windowManager,AbsListView与ListAdapter
12、享元模式:
池技术重要实现技术,减少重复对象的创建,通过享元工厂管理享元角色
应用场景:String字符串常量池
13、外观模式(门面模式):
对子系统进行封装,封装成一个类,调用封装类
行为型模式
14、策略模式:
抽象类实现策略方法,然后实现类实现,可以用来优化if-else语句结构
应用场景:ArrayAdapter与SimpleAdapter就是策略模式
15、状态模式:
与策略模式类似,但本质不同,不同行为有不同状态
16、责任链模式:
抽象类持有下一个引用(引用自身)
应用场景:ViewGroup与view事件分发
17、观察者模式:
观察者与主题(被观察者),主题通知观察者,主题发送,观察者接受并更新
应用场景:view的setOnClickListener监听
18、模板方法模式:
抽象类与实现类之间的关系,包括钩子方法(空实现或者返回Boolean)、抽象方法、具体方法
应用场景:view的draw()
19、迭代器模式:
容器接口中包含迭代器接口,在迭代器实现类中调用容器接口
应用场景:Map、List、Cursor
20、备忘录模式:
三个类之间的关系,一个发起人创建备忘录、一个备忘录、一个负责管理备忘录
应用场景:onSaveInstanceState和onRestoreInstanceState
21、访问者模式:
将数据结构与数据操作分离,适用于结构较稳定的元素操作上
22、中介者模式:
比如房产中介,将网状结构变为星状结构,中介只有通知功能,同事之间发送信息都通过中介
应用场景:android锁屏功能
23、解释器模式:
应用场景:AndroidManifest.xml通过PackageManagerService使用了PackageParser这个类来解释的
24、命令模式:
通过Command实现类控制接受、用户调用命令,接受者执行,实现了调用者和接受者之间解耦
应用场景:Handler(Handler接受者、Looper调用者、Message命令类)
未完待续~
好吧这是一篇很长的文章。。
鸣谢
https://ke.qq.com/course/341933享学课堂Mark、king老师