JUC
juc是放了一些进行多线程编程时有用的类
callable接口关注的是执行结果
带有返回值的线程
当我们使用多线程来计算一个数需要最终结果的值,而Thread类是没有返回值的,这时需要而外定义一个成员变量来接收这个值,当代码多了时就还需要判断此时这个成员变量是什么作用,对于阅读代码来说非常的不美观

可以使用callable来替代Thread进行,Callable是一个带有泛型参数的类,但是thread没有提供构造函数来传入callable

可以引用Futuretask来作为callable和thread的媒介

futuretask.get()是带有阻塞功能的,

ReentrantLock可重入锁
是一个传统锁,给对象提供了两个方法,加锁和解锁(lock,unlock)但是这种写法在加锁后容易忘记写解锁,且在unlock之前触发了return或者是异常就有可能引起unlock执行不到了,正确使用就需要把unlock放在finally里
ReentrantLock和synchronized的区别
1. ReentrantLock提供了trylock操作
lock直接进行加锁,若加锁不成功就要阻塞,trylock尝试进行加锁,加锁不成功不阻塞,直接返回false
2.ReentrantLock提供了公平锁的实现,遵循了先来后到,构造方法中填写参数,就可以设置成公平锁
synchronized是非公平锁
3.搭配的等待机制不同的
synchronized搭配wait/notify
reentrantlock搭配condition类功能比wait/notify略强一点
信号量semaphore
表示可用资源的个数,申请一个可用的资源就会使数字减一(acquire),释放一个可用资源就会使数字加一(release)
这里的初始值代表可用的资源有多少个,若可用资源为空,就会进行阻塞

信号量是更广义的锁, 锁本质上也是一种特殊的信号量
在代码中也可以保证线程安全

countdownlatch
把一个很大的文件拆分成多个部份,再让每个线程负责下载一部分,下载完成后,在把最终结果拼接在一起
实例化CountDownLatch后面的参数就是需要拆分成多少个线程来执行


hashmap和hashtable和ConcurentHashMap的区别
1.缩小了锁的粒度
hashmap是无锁的,是线程不安全的
hashtable是直接在方法上加锁,如果我们在不同的链表上修改,都会发生锁冲突,但是不涉及线程安全问题
concurrenthashmap则是在每个链表上加锁,在不同链表上修改则不会发生锁冲突,只有在同一个链表上修改才回发生锁冲突,且不会发生更过的空间代价,因为Java中锁的对象可以是任何一个对象,且哈希表中级必须要有数组,数组的元素都是存在的,只要使用数组元素作为锁的对象就可以
2.充分是使用了CAS原子操作,减少了一些加锁,针对哈希表元素个数的维护
3.针对扩容操作的优化
哈希表扩容是一个重量操作,因为哈希表中有负载因子,描述了每个桶上平均有多少个元素,此时桶上的链表的元素个数不应该太长,
hashmap的扩容操作是一把梭哈,在某次插入元素操作中,整体就完成扩容了
concurrenthashmap则是每次操作搬运一部分,扩容的时候每次进行增删改查的时候

浙公网安备 33010602011771号