Java中级知识归纳(三)

十一、Java垃圾回收机制

  Java的垃圾回收机制是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的内存空间。可以使用显式调用,System.gc();Runtime.getRuntime().gc();这两个方法调用时,用于显式通知JVM可以进行一次垃圾回收,但真正垃圾回收机制具体在什么时间点开始发生动作这同样是不可预料的,这和抢占式的线程在发生作用时的原理一样。

十二、类加载器、类加载时机

  类初始化的时机,有且仅有四个:A、遇到new、getstatic、putstatic、invokestatic这四条字节码指令的时候。

  B、使用java.lang.reflect进行反射调用的时候。

  C、当初始化一个类的时候,发现其父类还没有初始化,那么先去初始化它的父类。

  D、当虚拟机启动的时候,需要初始化main函数所在的类。

十三、Java IO和NIO的区别

  NIO操作直接缓存区,直接与OS交互,Selector IO复用机制。

  

IO   NIO  
面向流 面向缓冲
阻塞IO 非阻塞IO
选择器

  Selector:Java NIO的选择器允许一个单独的线程来监视多个输入通道,你可以注册多个通道使用一个选择器,然后使用一个单独的线程来“选择”通道,这些通道里已经有可以处理的输入,或者选择已准备写入的通道。这种选择机制,使得一个单独的线程很容易来管理多个通道。

  NIO与Netty:A、NIO的类库和API复杂,使用麻烦,需要熟练使用Selector、SeverSocketChannel、SocketChannel、ByteBuffer等。B、NIO涉及到Reactor模式,需要了解Java多线程和网络编程。C、JDKNIO Bug-epoll bug容易导致Selector空轮询,最终导致CPU100%占用,虽然JDK1.6update18修复了这个问题,但是直到JDK1.7问题依然存在,只是降低了发生的概率。

  Netty的优点:A、API简单,开发门槛低;B、功能强大,预置了多种解码功能,支持多种主流协议;C、可以通过ChannelHandler对通信框架进行灵活的扩展;D、性能高,Netty的综合性能是最好的;E、Netty修复了已经发现了所有的JDK NIO BUG ,成熟、稳定。

同步和异步的概念描述的是用户线程与内核的交互方式:同步是指用户线程发起IO请求后需要等待或者轮询内核IO操作完成后才能继续执行;而异步是指用户线程发起IO请求后仍继续执行,当内核Io操作完成后会通知用户线程,或者调用用户线程注册的回调函数。

  引申: 

Java中IO的种类和应用场景:

A、同步阻塞式:BIO。用于连接数目较小且固定的架构,对服务器资源占用高。

B、伪异步IO编程:线程池和任务队列。

C、NIO编程:a、缓冲区ByteBuffer;b、通道channel全双工,同时用于读写;c、多路复用器selector。用于连接数目多且较短的架构,如聊天服务器等,但是编程复杂,存在epoll bug,导致Selector空轮询,直至CPU占用达到100%,虽然在JDK1.6 update18中有对这个bug的修复,但是在JDK1.7中依然可能会出现这个问题,只是降低了bug出现的概率。

D、AIO编程:用于连接数目多且较长的架构,如相册服务器等,充分调用OS参与并发操作,基于JDK1.7。

  阻塞和非阻塞的概念描述的是用户线程调用内核IO操作的方式:阻塞是指IO操作需要彻底完成后才返回到用户空间;而非阻塞是指IO操作被调用后立即返回给用户一个状态值,无需等到IO操作彻底完成。

十四、Java锁机制

synchronized:把代码块声明为synchronized,有两个重要后果,通常是指该代码具有原子性和可见性。作用:A、当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。B、当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。C、尤其关键的是,当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。

A、原子性:原子性意味着一个时刻,只有一个线程能够执行一段代码,这段代码通过一个monitor object保护。从而防止多个线程在更新共享状态时相互冲突。

B、可见性:可见性则更为微妙,它要对付内存缓存和编译器优化的各种反常行为。它必须确保释放锁之前对共享数据做出的更改对于随后获得该锁的另一个线程是可见的。

C、volatile只保证可见性和禁止重排序,不保证原子性。

synchronized限制

A.它无法中断一个正在等候获得锁的线程;

B.也无法通过投票得到锁,如果不想等下去,也就没法得到锁;

C.同步还要求锁的释放只能在与获得锁所在的堆栈帧相同的堆栈帧中进行,多数情况下,这没问题(而且与异常处理交互得很好),但是,确实存在一些非块结构的锁定更合适的情况。

java.util.concurrent.lock:

ReentrantLock类实现了Lock,它拥有与synchronized相同的并发性和内存语义,但是添加了类似锁投票、定时锁等候和可中断等候的一些特征。此外,它还提供了在激烈争用情况下更佳的性能。

用sychronized修饰的方法或者语句块在代码执行完之后锁自动释放,而是用Lock需要我们手动释放锁,所以为了保证锁最终被释放(发生异常情况),要把互斥区放在try内,释放锁放在finally内。

ReentrantWriteReadLock中的ReadLock和WriteLock,在全为读时实现并发读,并发读写或者并发写时候加锁。

总结:synchronized是Java原语,阻塞的,竞争锁机制;新锁更加面向对象,,并且支持中断和支持公平锁。

十五、Java基本数据类型

boolean(1)、byte(8)、char(16)、short(16)、int(32)、float(32),long(64),double(64)

 

posted @ 2019-08-11 20:37  桃子dev  阅读(313)  评论(0编辑  收藏  举报