当前位置: 代码迷 >> 综合 >> 了解多线程常用的并发包
  详细解决方案

了解多线程常用的并发包

热度:98   发布时间:2023-11-02 05:03:35.0

CountDownLatch

CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。

public class Test002 {public static void main(String[] args) throws InterruptedException {System.out.println("等待子线程执行完毕...");CountDownLatch countDownLatch = new CountDownLatch(2);new Thread(new Runnable() {@Overridepublic void run() {System.out.println("子线程," + Thread.currentThread().getName() + "开始执行...");countDownLatch.countDown();// 每次减去1System.out.println("子线程," + Thread.currentThread().getName() + "结束执行...");}}).start();new Thread(new Runnable() {@Overridepublic void run() {System.out.println("子线程," + Thread.currentThread().getName() + "开始执行...");countDownLatch.countDown();System.out.println("子线程," + Thread.currentThread().getName() + "结束执行...");}}).start();countDownLatch.await();// 调用当前方法主线程阻塞  countDown结果为0, 阻塞变为运行状态System.out.println("两个子线程执行完毕....");System.out.println("继续主线程执行..");}}

CyclicBarrier

CyclicBarrier初始化时规定一个数目,然后计算调用了CyclicBarrier.await()进入等待的线程数。当线程数达到了这个数目时,所有进入等待状态的线程被唤醒并继续。 CyclicBarrier就象它名字的意思一样,可看成是个障碍, 所有的线程必须到齐后才能一起通过这个障碍。CyclicBarrier初始时还可带一个Runnable的参数, 此Runnable任务在CyclicBarrier的数目达到后,所有其它线程被唤醒前被执行。

 

Semaphore

Semaphore是一种基于计数的信号量。它可以设定一个阈值,基于此,多个线程竞争获取许可信号,做自己的申请后归还,超过阈值后,线程申请许可信号将会被阻塞。Semaphore可以用来构建一些对象池,资源池之类的,比如数据库连接池,我们也可以创建计数为1的Semaphore,将其作为一种类似互斥锁的机制,这也叫二元信号量,表示两种互斥状态。它的用法如下:

availablePermits函数用来获取当前可用的资源数量

semaphore.acquire(); //申请资源

semaphore.release();// 释放资源

// 创建一个计数阈值为5的信号量对象  // 只能5个线程同时访问  Semaphore semp = new Semaphore(5);  try {  // 申请许可  semp.acquire();  try {  // 业务逻辑  } catch (Exception e) {  } finally {  // 释放许可  semp.release();  }  } catch (InterruptedException e) {  }  

 

案例:

需求: 一个厕所只有3个坑位,但是有10个人来上厕所,那怎么办?假设10的人的编号分别为1-10,并且1号先到厕所,10号最后到厕所。那么1-3号来的时候必然有可用坑位,顺利如厕,4号来的时候需要看看前面3人是否有人出来了,如果有人出来,进去,否则等待。同样的道理,4-10号也需要等待正在上厕所的人出来后才能进去,并且谁先进去这得看等待的人是否有素质,是否能遵守先来先上的规则。

代码:

class Parent implements Runnable {private String name;private Semaphore wc;public Parent(String name,Semaphore wc){this.name=name;this.wc=wc;}@Overridepublic void run() {try {// 剩下的资源(剩下的茅坑)int availablePermits = wc.availablePermits();if (availablePermits > 0) {System.out.println(name+"天助我也,终于有茅坑了...");} else {System.out.println(name+"怎么没有茅坑了...");}//申请茅坑 如果资源达到3次,就等待wc.acquire();System.out.println(name+"终于轮我上厕所了..爽啊");Thread.sleep(new Random().nextInt(1000)); // 模拟上厕所时间。System.out.println(name+"厕所上完了...");wc.release();} catch (Exception e) {}}
}
public class TestSemaphore02 {public static void main(String[] args) {// 一个厕所只有3个坑位,但是有10个人来上厕所,那怎么办?假设10的人的编号分别为1-10,并且1号先到厕所,10号最后到厕所。那么1-3号来的时候必然有可用坑位,顺利如厕,4号来的时候需要看看前面3人是否有人出来了,如果有人出来,进去,否则等待。同样的道理,4-10号也需要等待正在上厕所的人出来后才能进去,并且谁先进去这得看等待的人是否有素质,是否能遵守先来先上的规则。Semaphore semaphore = new Semaphore(3);for (int i = 1; i <=10; i++) {Parent parent = new Parent("第"+i+"个人,",semaphore);new Thread(parent).start();}}
}

 

  相关解决方案