Java并发包——并发工具

Java并发工具:

知识点:Thread.join()是通过Object.wait()来实现的,Thread.join(millis)是通过Object,wait(millis)来实现的。当线程执行完后,由JVM调用Thread.unpark$()方法->Object.notifyAll()。

(1)CountDownLatch(计数器):
相当于一个计数器,它的构造函数会传入一个int值作为初始计数值。但是这个计数器是一次性的,不可重复使用。
- await():线程调用该方法,相当于这个线程需要等到计数器的值归0后才会从await()方法返回。当然如果通过其他线程中断这个线程的话,就会抛出中断异常,也会导致当前线程从await()方法返回。
- await(millis):跟上面一样,只是这个方法有时间限制,时间到了也会从await()方法返回。
- countDown():线程调用该方法,导致计数器的值减一,使用CAS操作减一。
它的等待和唤醒都是通过LockSupport.park()和LockSupport.unpark()实现。

(2)CyclicBarrier(同步屏障):
它的构造函数会传入一个int值作为等待n个线程到达屏障处,另一个参数是Runnable,表示当最后一个线程到达屏障处就会执行这个Runnable的run()方法。可以多次使用。
- await():线程调用该方法,表示当前线程已经完成了任务,到达了屏障处,count减一。当然如果通过其他线程中断这个线程的话,就会抛出中断异常,也会导致当前线程从await()方法返回。
- await(millis):跟上面一样,只是这个方法有时间限制,时间到了也会从await()方法返回。
它的等待和唤醒都是通过Condition.await()和Condition.signal()来实现的。但然后Condition的实现原理也是通过LockSupport.park()和LockSupport.unpark()实现

(3)Semaphore(信号量):
它的构造函数会传入一个int值作为同一时刻最多允许同时访问资源的线程数。
- acquire():线程调用该方法,表示需要获取一个凭证来访问这个资源,如果这个资源访问剩余名额不足1,则当前线程等待在此处,否则就获取这个凭证访问资源。当然如果通过其他线程中断这个线程的话,就会抛出中断异常,也会导致当前线程从cquire()方法返回。
- release():线程调用该方法,表示任务完成了,不再需要访问这个资源,就会释放这个凭证,同时其他正在等待的获取凭证的线程就可以获取到一个凭证来访问资源。
acquire()方法获取凭证,如果1.没有剩余凭证或者2.有剩余凭证就通过循环CAS操作获取凭证,不成功,那么就会通过LockSupport.park()方法将当前线程加入到等待队列。
release()方法通过CAS将可获取的凭证数量加一,并且唤醒在等待队列里的线程。
这里只介绍主要方法,其他方法自行参照API。

(4)Exchanger(资源交换者):
Exchanger接收一个泛型,表示需要交换的资源的类型。构造函数是无参的。
- exchange(T):一个线程调用该方法将数据作为参数传入,另一个线程调用该方法将数据作为参数传入。只有当两个线程都调用了这个方法,才会从这个方法的返回值中获取交换后的数据,如果只有一个线程调用了这个方法,那么这个线程就会等待,直到下一个线程调用了该方法。当然如果通过其他线程中断这个线程的话,就会抛出中断异常,也会导致当前线程从exchange()方法返回。
- exchange(V x, long timeout, TimeUnit unit):比上面的方法多了一个超时时间,避免等待太久。
exchange方法是通过Unsafe.park()和Unsafe.unpark()方法来实现等待和唤醒的。当然LockSupport的实现原理也是通过Unsafe来实现的。

你可能感兴趣的:(Java)