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则是每次操作搬运一部分,扩容的时候每次进行增删改查的时候

posted @ 2025-03-31 15:05  油头男孩  阅读(10)  评论(0)    收藏  举报