赞
踩
java集合由两个接口实现,Collection接口用于存放单一元素,Map接口用于存放键值对。
1.Hashtable & HashMap & ConcurrentHashMap
HashMap:
Hashtable:
底层采用了数组+链表,但是内部方法使用了synchronized关键字修饰,是线程安全的。但是由于一个线程访问的时候其他线程无法访问,效率比HashMap低。
ConcurrentHashMap:
JDK1.7之前:使用数组+链表实现,线程安全,使用Segment分段锁的方式,将数组分成一段一段的,当a段加锁时b段还能被其他线程访问。
JDK1.8及之后:数组+链表+红黑树,丢弃分段锁,使用CAS+Sychronized实现并发安全性。锁的粒度更小。
参考链接
2.进程与线程
进程是程序执行的一次过程,是动态的。而线程是比进程更小的执行单位,是cpu运行的基本单位。
条件:
1.请求并保持条件:一个线程因获取资源而阻塞时,对已获取的资源保持不放。
2.不可剥夺条件:线程自己获得的资源在没使用完自己其他线程不可强行剥夺,只有自己使用完才释放资源
3.互斥条件:该资源任何时刻只能由一个线程占用。
4.循环等待条件:若干线程形成一种头尾相接的环形等待资源关系。
预防死锁:
1.破坏请求并保持:一次性申请所有资源
2.破坏不可剥夺条件: 一个线程获取部分资源后继续获取其他资源,如果申请不到,可以释放它所占用的资源。
1.NEW: 初始状态,线程被创建出来但没有被调用 start() 。
2.RUNNABLE: 运行状态,线程被调用了 start()等待运行的状态。
3.BLOCKED:阻塞状态,需要等待锁释放。4.WAITING:等待状态,表示该线程需要等待其他线程做出一些特定动作(通知或中断)。5.TIME_WAITING:超时等待状态,可以在指定的时间后自行返回而不是像 WAITING 那样一直等待。
6.TERMINATED:终止状态,表示该线程已经运行完毕
3.可以直接调用Thread类的run方法吗?
最好不要,因为只有调用start()方法才会启动一个线程然后等时间片到的时候运行run()方法的内容。而直接调用run方法会把它当成是main程序下的一个普通方法执行。
4.volatile关键字
保证变量的可见性、禁止指令重排(插入内存屏障)。但是无法保证变量的原子性。使用volatile关键字的变量,线程读取的时候会从共享内存中读取,改写关键字后会同步刷新到共享内存。
5.乐观锁与悲观锁
存在的问题:
1.ABA问题:在A被修改为B之后可能修改为A,但是线程可能认为没有被修改。解决办法:加上时间戳或者版本号。
2.循环时间开销大:CAS会使用自旋操作进行不断重试。
6.synchronized
monitorenter,在判断拥有同步标识ACC_SYNCHRONIZED时会抢先进入线程,拥有Minitor的owner,计数器+1,执行完后计数器-1归0,被其他线程获得。
7.ReentrantLock和Synchronized的区别
8.ThreadLocal
原理:每个线程都有一个ThreadLocalMap用来存储线程局部变量。当使用set方法时,会先获取线程的ThreadLocalMap对象,然后依据ThreadLocal计算出键值对存放的索引位置。
内存泄漏:ThreadLocal作为key是弱引用,而value是强引用。当线程不引用ThreadLocal时,ThreadLocal被回收,key为null,而value永远无法被GC回收,就会存在内存泄漏问题。
9.AQS
是一个抽象类,主要用来构建锁和同步器。如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制 AQS 是用 CLH 队列锁 实现的,即将暂时获取不到锁的线程加入到队列中。
CLH队列是双向队列,每个节点代表一个线程,其中有一个volatile关键字state(资源)表示同步状态,通过CAS更改。
--------------------------待更新-----------------------------------------------------
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。