java基础知识总结二

时间:2022-09-18 23:37:27

1. synchronized和reentrantlock异同

相同点
都实现了多线程同步和内存可见性语义
都是可重入锁
不同点
实现机制不同 synchronized通过java对象头锁标记和Monitor对象实现 reentrantlock通过CAS、ASQ(AbstractQueuedSynchronizer)和locksupport(用于阻塞和解除阻塞)实现 synchronized依赖jvm内存模型保证包含共享变量的多线程内存可见性 reentrantlock通过ASQ的volatile state保证包含共享变量的多线程内存可见性
使用方式不同 synchronized可以修饰实例方法(锁住实例对象)、静态方法(锁住类对象)、代码块(显示指定锁对象) reentrantlock显示调用trylock()/lock()方法,需要在finally块中释放锁
 
功能丰富程度不同 reentrantlock提供有限时间等候锁(设置过期时间)、可中断锁(lockInterruptibly)、condition(提供await、signal等方法)等丰富语义 reentrantlock提供公平锁和非公平锁实现 synchronized不可设置等待时间、不可被中断(interrupted)

2. concurrenthashmap为何读不用加锁

 
jdk1.7
1)HashEntry中的key、hash、next 均为final 型,只能表头插入、删除结点
2)HashEntry类的value域被声明为volatile型
3)不允许用null作为键和值,当读线程读到某个HashEntry的 value域的值为null时,便知道产生了冲突——发生了重排序现象(put设置新value对象的字节码指令重排序),需要加锁后重新读入这个value值
4)volatile变量count协调读写线程之间的内存可见性,写操作后修改count,读操作先读count,根据happen-before传递性原则写操作的修改读操作能够看到
jdk1.8
1)Node的val和next均为volatile型
2)tabAt和casTabAt对应的unsafe操作实现了volatile语义

3. ContextClassLoader(线程上下文类加载器)的作用

 
越过类加载器的双亲委派机制去加载类,如serviceloader实现
使用线程上下文类加载器加载类,要注意保证多个需要通信的线程间的类加载器应该是同一个,防止因为不同的类加载器导致类型转换异常(ClassCastException)。
 

4. tomcat 类加载机制

java基础知识总结二java基础知识总结二
不同应用使用不同的 webapp类加载器,实现应用隔离的效果,webapp类加载器下面是jsp类加载器
不同应用共享的jar包可以放到Shared类加载器/shared目录下。
 

5. osgi类加载机制

java基础知识总结二java基础知识总结二
 
osgi类加载模型是网状的,可以在模块(Bundle)间互相委托
osgi实现模块化热部署的关键是自定义类加载器机制的实现,每个Bundle都有一个自己的类加载器,当需要更换一个Bundle时,就把Bundle连同类加载器一起换掉以实现代码的热替换
 
当收到类加载请求时,osgi将按照下面的顺序进行类搜索:
1)将以java.*开头的类委派给父类加载器加载
2)否则,将委派列表名单(配置文件org.osgi.framework.bootdelegation中定义)内的类委派给父类加载器加载
3)否则,检查是否在Import-Package中声明,如果是,则委派给Export这个类的Bundle的类加载器加载
4)否则,检查是否在Require-Bundle中声明,如果是,则将类加载请求委托给required bundle的类加载器
5)否则,查找当前Bundle的ClassPath,使用自己的类加载器加载
6)否则,查找类是否在自己的Fragment Bundle中,如果在,则委派给Fragment Bundle的类加载器加载
7)否则,查找Dynamic Import-Package(Dynamic Import只有在真正用到此Package的时候才进行加载)的Bundle,委派给对应Bundle的类加载器加载
8)否则,类查找失败。
 

6. 如何结束一个一直运行的线程

 
使用退出标志,这个flag变量要多线程可见
使用interrupt,结合isInterrupted()使用。

7. threadlocal使用场景及问题

 
threadlocal并不能解决多线程共享变量的问题,同一个 threadlocal所包含的对象,在不同的thread中有不同的副本,互不干扰
 
用于存放线程上下文变量,方便同一线程对变量的前后多次读取,如事务、数据库connection连接,在web编程中使用的更多
 
问题: 注意线程池场景使用threadlocal,因为实际变量值存放在了thread的threadlocalmap类型变量中,如果该值没有remove,也没有先set的话,可能会得到以前的旧值
 
问题: 注意线程池场景下的内存泄露,虽然threadlocal的get/set会清除key(key为threadlocal的弱引用,value是强引用,导致value不释放)为null的entry,但是最好remove。
 

8. 线程池从启动到工作的流程

刚创建时,里面没有线程
调用 execute() 添加任务时:
1)如果正在运行的线程数量小于核心参数corePoolSize,继续创建线程运行这个任务
2)否则,如果正在运行的线程数量大于或等于corePoolSize,将任务加入到阻塞队列中
3)否则,如果队列已满,同时正在运行的线程数量小于核心参数maximumPoolSize,继续创建线程运行这个任务
4)否则,如果队列已满,同时正在运行的线程数量大于或等于 maximumPoolSize,根据设置的拒绝策略处理
5)完成一个任务,继续取下一个任务处理
6)没有任务继续处理,线程被中断或者线程池被关闭时,线程退出执行,如果线程池被关闭,线程结束
7)否则,判断线程池正在运行的线程数量是否大于核心线程数,如果是,线程结束,否则线程阻塞。因此线程池任务全部执行完成后,继续留存的线程池大小为corePoolSize。
 

9. 阻塞队列BlockingQueue take和poll区别

 
poll(time):取走BlockingQueue里排在首位的对象,若不能立即取出,则可以等time参数规定的时间,取不到时返回null
take():取走BlockingQueue里排在首位的对象,若BlockingQueue为空,阻塞直到BlockingQueue有新的对象被加入。

10. 如何从FutureTask不阻塞获取结果

 
get(long timeout,TimeUnit unit),超时则返回
轮询,先通过isDone()判断是否结束,然后调用get()。
 

11. blockingqueue如果存放了比较关键的数据,系统宕机该如何处理

 
开放性问题,欢迎讨论
将队列持久化,比较麻烦,需要将生产数据持久化到磁盘,持久化成功才返回,消费者线程从磁盘加载数据到内存阻塞队列中,维护消费offset,启动时,根据消费offset从磁盘加载数据
加入消息队列,保证消息不丢失,生成序列号,消费幂等,根据消费进程决定系统重启后的生产状态。
 

12. NIO与传统I/O的区别

 
节约线程,NIO由原来的每个线程都需要阻塞读写变成了由单线程(即Selector)负责处理多个channel注册(register)的兴趣事件(SelectionKey)集合(底层借助操作系统提供的epoll()),netty bossgroup处理accept连接(没看明白为什么bossgroup设置多个thread的必要性),workergroup处理具体业务流程和数据读写
NIO提供非阻塞操作
传统I/O 以流的方式处理数据,而 NIO 以块的方式处理数据,NIO提供bytebuffer,分为堆内和堆外缓冲区,读写时均先放到该缓冲区中,然后由内核通过channel传输到对端,堆外缓冲区不走内核,提升了性能。
 

13. list中存放可重复字符串,如何删除某个字符串

 
调用iterator相关方法删除
倒删,防止正序删除导致的数组重排,index跳过数组元素问题。

14. 有哪些GC ROOTS(跟日常开发比较相关的是和此相关的内存泄露)

 
所有Java线程当前活跃的栈帧里指向GC堆里的对象的引用,因此用不到的对象及时置null,提升内存回收效率
静态变量引用的对象,因此减少静态变量特别是静态集合变量的大小,集合存放的对象覆写euqls()和hashcode(),防止持续增长
本地方法JNI引用的对象
方法区中的常量引用的对象,因此减少在长字符串上调用String.intern()
classloader加载的class对象,因此自定义classloader无效时及时置null并且注意类加载器加载对象之间的隔离
jvm里的一些静态数据结构里指向GC堆里的对象的引用

java基础知识总结二的更多相关文章

  1. java基础知识(二)-----多态和构造函数

    一:前言 最近由于面试了新浪公司,面试官问我的问题我都不知道,觉得自己好菜,所以最近决定再把java基础给搞一遍,真的觉得自己好菜.每天看一点,那个家伙说<java编程思想>最少要看三遍, ...

  2. Java基础知识(二)

    一.基本概念 1. Java程序初始化的顺序是怎么样的 2. Java和C++的区别 3. 反射 先看一个知乎回答 什么是反射 主要用途 获得Class对象 4. 注解 什么是注解 为什么要用注解 基 ...

  3. Java 基础知识总结 &lpar;二、基本数据类型&rpar;

    二.基本数据类型 java基本数据类型只能先声明后使用 boolean  true/false char 16-bit unicode character byte 8-bit integer sho ...

  4. Java基础知识陷阱&lpar;二&rpar;

    本文发表于本人博客. 上次说了一些关于字符串的知识,都是比较基础的,那这次也说下关于对象地址问题,比如传参.先看下面代码: public void changeInt(int a){ a = ; } ...

  5. Java测试开发--Java基础知识(二)

    一.java中8大基本类型 数值类型:byte.short.int .float.double .long 字符类型:char 布尔类型:boolean 二. 封装:将属性私有化,不允许外部数据直接访 ...

  6. java基础知识(二)字符串处理

    字符串是程序开发中使用最为频繁,因此为了工作的高效和作为一名想进阶的程序员,了解并掌握字符串的处理显得尤为重要.java为我们提供了String.StringBuffer.StringBuilde三个 ...

  7. java基础知识拾遗&lpar;二&rpar;

    1.finally public static int func (){ try{ return 1; }catch (Exception e){ return 2; }finally { retur ...

  8. java基础知识总结&lpar;二&rpar;

    +=隐含了强制类型转换. x+=y;等价与:x = (x的数据类型)(x + y); 函数重载? 函数名同样.參数列表不同.跟返回值不关,就是函数重载 封装是什么? 隐藏对象的属性和详细的实现细节,仅 ...

  9. Scanner、String&lpar;java基础知识十二&rpar;

    1.Scanner的概述和方法介绍 * A:Scanner的概述 * 是一个从键盘输入的类,有final修饰,不能被子类继承 * Scanner sc = new Scanner(System.in) ...

随机推荐

  1. 4-iscsi

    Iscsi 1.       创建lvm 2.       安装scsi服务端软件包 第一种(命令模式) 第二种(配置文件模式) 客户端 Node1 寻找scsi服务器上的储存设备 将scsi设备挂载 ...

  2. Leetcode 131&period; Palindrome Partitioning

    Given a string s, partition s such that every substring of the partition is a palindrome. Return all ...

  3. 关于Spatial referencing by geographical identifiers 标准

    地理信息空间参考大体可以分为两类,ISO给出了分类:Spatial referencing by geographical identifiers(根据地理标识符的空间定位,ISO 19112)与Sp ...

  4. 18、ESC&sol;POS指令集在android设备上使用实例(通过socket)

    网上关于通过android来操作打印机的例子太少了,为了方便更多的开发同仁,将近日所学分享一下. 我这边是通过android设备通过无线来对打印机(佳博58mm热敏式-58130iC)操作,实现餐厅小 ...

  5. First step of using junit---------Software Testing Lab 1---2016&period;03&period;18

    1. Install junit a)      Download “junit.jar” b)      In eclipse, Windows->Preferences->Java-& ...

  6. Memcached 配置 和项目应用

    Memcached 配置 http://blog.csdn.net/sup_heaven/article/details/32337711 memcached真实项目中的应用 http://blog. ...

  7. kettle中文乱码问题

    db连接->选项 配置参数 characterEncoding,设置值为gbk/utf8.

  8. install pycurl

    error: command 'x86_64-linux-gnu-gcc' failed with exit status 1src/pycurl.h:164:28: fatal error: ope ...

  9. 利用Form组件和ajax实现的注册

    一.注册相关的知识点 1.Form组件 我们一般写Form的时候都是把它写在views视图里面,那么他和我们的视图函数也不影响,我们可以吧它单另拿出来,在应用下面建一个forms.py的文件来存放 2 ...

  10. postgreSQL数据库的监控及数据维护

    目前postgreSQL数据库的管理,数据查询等都需要安装postgreSQL软件或安装pgadmin等,远程访问都需要先登录到服务器等繁琐的操作.如果是开发团队,那么每个开发,测试,管理人员都要经历 ...