Java面经总结

来源:互联网 发布:python接口测试 编辑:程序博客网 时间:2024/05/22 02:28

线程安全

1.什么是不安全?

 1.1 不同线程,对同一资源的访问或修改。 1.2 原子性   JVM规范定义了线程对主存的操作指令:read,load,use,assign,store,write 1.3 可见性------------------------------------------------volatile,final,synchronized, 1.4 有序性-------------read-load,从主存加载数据到线程自己的工作内存中,即保留一个副本,assign,修改之后, 变量副本会同步到主存储区(store- write),何时同步不一定,导致最后在内存中的值不是想象中的。

2.为什么会产生?

 1. CPU高速缓存 2、主内存

3.如何避免?

1.强同步:synchronized 关键字。 当一段代码会修改共享变量,这一段代码成为互斥区或临界区,用synchronized标识起来,共享对象作为锁,否则没有意义。

     每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列,就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程,当一个被线程被唤醒 (notify)后,才会进入到就绪队列,等待cpu的调度

一个线程执行临界区代码过程如下:
1 获得同步锁
2 清空工作内存
3 从主存拷贝变量副本到工作内存
4 对这些变量计算
5 将变量从工作内存写回到主存
6 释放锁

2.生产者/消费者模式

      lock.wait   -----释放锁,      lock.notify  ----通知lock中阻塞队列里面的某个线程,进入就绪队列。      lcok.notifyAll ---通知所有阻塞队列里的线程。    3.volitle      对变量修改回写到内存,相当于 (store- write)       防止指令重排    4.共享对象不可变     5.原子操作,原子类,底层CAS实现,但是会导致缓存一致性流量,bus风暴,性能降低            MESI协议实现,

底层实现:

 1.read,load,assign,use,store,write (底层原子操作) 2.lock,unlock.开放api给用户用,字节码为monitorenter,monitorexit   (Syncronized 关键字的底层)   其实是对象头,包含一个锁的位置:

对象头:

http://blog.csdn.net/hsuxu/article/details/9472371
这里写图片描述
包含,锁的升级,可升不可降

各种锁:

1. ReentrantLock在同步竞争不激烈时用synchronized,激烈时用ReentrantLock ReentrantLock提供了lockInterruptibly()方法可以优先考虑响应中断,而不是像synchronized那样不响应interrupt()操作同一个线程,持有锁,可以重新获取该锁,即重进入,避免了死锁,内部实现有一个计数器和一个标志位,标志占有的线程。需要手动释放锁2.synchronized + 内部锁,或叫互斥锁,会阻塞或等待,直到获取锁,无法重进入,产生死锁     +static 类锁3.公平锁,非公平锁          公平锁是指多个线程在等待同一个锁时,必须按照申请锁的先后顺序来一次获得锁。4.自旋锁      线程执行一个忙循环(自旋),等待其他线程释放锁。5.其他![这里写图片描述](http://img.blog.csdn.net/20160912192430196)

并发工具

一.CountDownLatch用法await()await(long timeout,TimeUnit unit)countDown();二.CyclicBarrier用法await()await(long timeout,TimeUnit unit)   第一个版本比较常用,用来挂起当前线程,直至所有线程都到达barrier状态再同时执行后续任务;  第二个版本是让这些线程等待至一定的时间,如果还有线程没有到达barrier状态就直接让到达barrier的线程执行后续任务。三.Semaphore用法1234public void acquire() throws InterruptedException {  }     //获取一个许可public void acquire(int permits) throws InterruptedException { }    //获取permits个许可public void release() { }          //释放一个许可public void release(int permits) { }    //释放permits个许可控制资源能够被多少线程访问,类似于锁。

class 加载

双亲委派模型的工作流程是:如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类。

c++——-> bootstrap classloader ———->extension classloader —-> application classloader ——–>selfdefined classloader

垃圾回收

这里写图片描述

1. new Object --> eden , if not enough ---> YoungGC(Minor GC)2. Survivor Mem not enough ---> YoungGC(Major GC    : Old Generation)3. Old Generation Mem not enough ---> Full GC  (Old: CMS)

引用算法:

引用分类:强,软,弱,虚

1.引用计数, 存在循环引用2.可达性分析算法,即判断一个对象能否到达GC-roots,GC-roots:虚拟机栈(栈帧中的本地变量表)中引用的对象。方法区中类静态属性引用的对象。方法区中常量引用的对象。本地方法栈中JNI(即一般说的Native方法)引用的对象。垃圾收集算法:1.标记-清除  ,直接清除当前位置。2.复制算法   即复制到另一半,然后回收另一半,一块大eden区,两块小survivor区,将eden区中存活的复制到一块空的survivor区,清理eden和第一个survivor3.标记-整理,然所有存活对象移动到另一端,清除另一端。4.分代收集5.hot-spot的实现:          各个收集器。采用不同的垃圾收集算法          5.1 serial 收集器,单线程,新生代收集器,标记-整理          5.2 ParNew,多线程的serial。          5.3 Parallel Scavenge,新生代,复制算法。          5.4 serial-old          5.5 ParalleOld          5.6 CMS,很短暂的停顿。不会stop the world,标记-清除eden----> survivor--->old---->perm年龄,大对象,往后放

6.G1收集器,牛逼,即 将jvm的堆区,划分为大小相等的region,remembered Set (referrence counting)

分为以下4各阶段:

初始标记(GCroots)并发标记最终标记筛选回收
1 .分代收集:仍然有分代的概念,不需要其他收集器配合,独立管理整个GC堆。2 .空间整合:从整体看,是基于“标记-整理”算法实现的,从局部(两个Region之间)看是基于“复 制”算法的。在运行期间不会产生内存碎片。3 .可预测的停顿:G1跟踪各个Region里垃圾堆积值的价值大小,维护一个优先级队列,每次根据允许 的时间,优先回收价值最大的Region。(这也是Garbage First的由来)

虚拟机GC参数设置

http://unixboy.iteye.com/blog/174173-Xms   -Xmx   JVM 最大内存-Xmn   年轻代大小-XX:SuvirorRatio=8  eden:survivor = 8:1-XX:PretenureSizeThreshold   设置大对象阈值,超过,则直接分配到老年代 只对 parnew 和Serail 收集器有效-XX:MaxPretenuringThreshold 设置晋升old的阈值  即age的max-XX:+UseParNewGC:-XX:+UseG1GCeden --> survivor age:1minor GC, age ++if age >= 15 ----> Old Generation

Class:

这里写图片描述

1.Magic Num :0xCAFFEBABE2.constant_pool :    1. literal    2. reference name

底层进阶:

线程实现

1.使用内核线程实现(KLT)。由内核分配,内核Scheduler调度。 但一般用LWP(轻量级进程),即KLT的一种接口。(user mode ,kernel mode切换消耗资源)

这里写图片描述

2.使用用户线程实现

这里写图片描述

3.LWP和用户线程混合
这里写图片描述
SunJdk中用LWP(win,linux)

线程调度(java,抢占式)

这里写图片描述

常见集合原理源码

这里写图片描述

Map系: HashMap,LinkedHashMap,TreeMap, WeakHashMap, EnumMap,ConcurrentHashMapList系:ArrayList, LinkedList, Vector, StackSet系:HashSet, LinkedHashSet, TreeSet
1 0
原创粉丝点击