Java JUC包下Tools

it2024-01-30  63

1.2 CountDownLatch

1.2.1 什么是CountDownLatch


latch-门栓 countdown-倒数。 倒数到0门栓打开。

CountDownLatch是在java1.5被引入的,跟它一起被引入的并发工具类还有CyclicBarrier、Semaphore、ConcurrentHashMap和BlockingQueue,它们都存在于java.util.concurrent包下。CountDownLatch这个类能够使一个线程等待其他线程完成各自的工作后再执行。例如,应用程序的主线程希望在负责启动框架服务的线程已经启动所有的框架服务之后再执行。

CountDownLatch的一个非常典型的应用场景是:有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以继续往下执行。

当然也可以使用join实现,但是比join灵活的多:t.join() 会阻塞当前线程,直到t线程执行完毕。但是CountDownLatch不一定要等到线程执行完毕,它可以在任何时候countdown。

这个类非常简单只有两个方法:

countDown() :使count属性递减1

await():阻塞当前线程,直到count属性变为0,或被interrupt

1.2.2 使用实例


public static void HowToUse(){ Thread[] threads = new Thread[100]; CountDownLatch latch = new CountDownLatch(threads.length); for (int i = 0; i < threads.length; i++) { threads[i] = new Thread(()->{ int result = 0; for (int j = 0; j <1000000; j++) { result += j; } System.out.println(Thread.currentThread().getName()+":模块启动完毕"); latch.countDown();//count属性递减 }); } for (Thread thread : threads) { thread.start(); } try { latch.await();//等待,直到count属性变为0 } catch (InterruptedException e) { e.printStackTrace(); } //执行主程序代码 System.out.println("所有模块启动完毕!主程序启动!");//我们希望在这100个线程结束后打印这一句话 }

1.3 CyclicBarrier


从字面上理解就是循环栅栏,当线程达到了一定的数量这个栅栏就开放,之后再关闭,然后循环往复。

public static void HowToUse(){ CyclicBarrier barrier = new CyclicBarrier(20,()-> System.out.println("线程达到20个!")); // CyclicBarrier barrier = new CyclicBarrier(20, new Runnable() { // @Override // public void run() { // System.out.println("线程达到20个!"); // } // }); for (int i = 0; i <100 ; i++) { new Thread(()->{ try { barrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } }).start(); } } public static void main(String[] args) { HowToUse(); }

1.4 Phaser


1.5 semaphore


这里的semaphore就是我们在操作系统上学到的semaphore是一样的。

首先我们new一个semaphore,传入一个int类型,我么亦可以指定它为公平或不公平

之后每调用一次acquire(),信号量的值就-1,当信号量为0时,线程就会被阻塞;

调用release()会使信号量+1

它可以用来 限流。 比如最多只允许10个线程同时运行

注意⚠️:它与newfixedThreadPool可不一样,这个线程池是规定池子里的最大线程数是多少,以及核心线程数是多少,至于线程要不要同步等等线程池都是不管的。而semaphore是只有acquire到的线程才可以执行,没有acquire到的线程就阻塞

public class SemaphoreTest { public static void main(String[] args) { Semaphore s = new Semaphore(3,true); Thread[] threads = new Thread[30]; for (int i = 0; i <threads.length ; i++) { threads[i] = new Thread(()->{ try { s.acquire(); System.out.println(Thread.currentThread().getName()+": 我acquire到了"); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }finally { s.release(); } }); } for(Thread thread:threads){ thread.start(); } } }

1.6 Exchanger


Exchanger意思为交换者,作为Java并发工具类他的作用是交换过个线程中的数据。它提供一个同步点,在这个同步点,两个线程可以交换彼此的数据。当第一个线程调用exchange()方法,那么他会进入阻塞状态一直等待第二个线程调用exchange()方法,我们也可以设置一个timeout。直到交换数据。

交换数据只能是两个线程之间进行,不存在多个线程之间交换数据

代码示例:https://www.cnblogs.com/gemine/p/9054985.html~~~~

最新回复(0)