前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >多线程工具类:CountDownLatch、CyclicBarrier、Semaphore、LockSupport

多线程工具类:CountDownLatch、CyclicBarrier、Semaphore、LockSupport

作者头像
Java学习录
发布2019-04-18 14:56:23
4020
发布2019-04-18 14:56:23
举报
文章被收录于专栏:Java学习录

CountDownLatch

假如有一个任务想要往下执行,但必须要等到其他的任务执行完毕后才可以。

比如你想要买套房子,但是呢你现在手上没有钱。你得等这个月工资发了、然后年终奖发了、然后朋友借你得钱还给你了、然后再给朋友借一部分才可以买,这种场景你就可以使用CountDownLatch。

CountDownLatch是JDK为我们提供的一个计数器,它的操作是原子操作,同一时间只能有一个线程去操作这个它。

我们先来看一下CountDownLatch的主要方法。

代码语言:javascript
复制
//构造方法,接收计数器的数量public CountDownLatch(int count)//持续等待计数器归零public void await()//最多等待unit时间单位内timeout时间public boolean await(long timeout, TimeUnit unit)//计数器减1public void countDown()//返回现在的计数器数量public long getCount()

下面是CountDownLatch的基本使用示例代码:

代码语言:javascript
复制
public class CountDownLatchDemo {    public static CountDownLatch countDownLatch = new CountDownLatch(5);    static class ThreadDemo extends Thread {        @Override        public void run() {            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println(Thread.currentThread().getId() + "完成任务");            countDownLatch.countDown();        }    }    public static void main(String[] args) throws InterruptedException {        for (int i = 0; i < 5; i++) {            new ThreadDemo().start();        }        countDownLatch.await();        System.out.println("全部完成任务");    }}

CyclicBarrier

相比较于CountDownLatch,CyclicBarrier可以完成前者的全部功能,但是相比前者,它的功能更加的强大。

  1. CyclicBarrier翻译过来的中文名称叫循环栅栏,顾名思义它可以循环使用
  2. CyclicBarrier还可以接收一个Runnable对象,当栅栏循环一次技术后会执行一次Runnable

我们来看一下CyclicBarrier的常用方法:

代码语言:javascript
复制
//构造方法,第一个参数为栅栏饿长度,第二个就是上方所说的Runnable对象public CyclicBarrier(int parties, Runnable barrierAction)public CyclicBarrier(int parties)//获取现在的数量public int getParties()//持续等待栅栏归零public int await()//最多等待unit时间单位内timeout时间public int await(long timeout, TimeUnit unit)

下面是CyclicBarrier的基本使用示例代码:

代码语言:javascript
复制
public class CyclicBarrierDemo {    public static CyclicBarrier cyclicBarrier = new CyclicBarrier(5,new FinallyThreadDemo());    static class ThreadDemo extends Thread {        @Override        public void run() {            try {                Thread.sleep(1000);                System.out.println(Thread.currentThread().getId() + "完成任务");                cyclicBarrier.await();            } catch (InterruptedException e) {                e.printStackTrace();            } catch (BrokenBarrierException e) {                e.printStackTrace();            }            System.out.println("到达屏障点每个线程都会瞬时继续执行");        }    }    static class FinallyThreadDemo extends Thread {        @Override        public void run() {            System.out.println("所有任务已经完成之后单独执行的任务!");        }    }    public static void main(String[] args) throws InterruptedException {        for (int i = 0; i < 10; i++) {            new ThreadDemo().start();        }    }}

观察打印结果我们可以发现:

当循环栅栏的任务执行完一轮以后,如果构造时传入了Runnable对象,则先执行Runnable对象,然后在瞬间释放所有任务的锁。

代码语言:javascript
复制
14完成任务15完成任务16完成任务17完成任务18完成任务所有任务已经完成之后单独执行的任务!到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行19完成任务20完成任务21完成任务22完成任务23完成任务所有任务已经完成之后单独执行的任务!到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行到达屏障点每个线程都会瞬时继续执行

Semaphore

浅谈Java中的锁:Synchronized、重入锁、读写锁 一文中,我们了解了synch和读写锁,我们发现使用锁的时候一次只允许一条线程方法。那么有什么东西可以提供更强大的控制方法么?这个东西就是信号量。

信号量提供的主要方法:

代码语言:javascript
复制
//创建具有给定许可数的信号量Semaphore(int permits):构造方法,创建//拿走1个许可void acquire()//拿走多个许可void acquire(int n)//释放一个许可void release()//释放n个许可void release(int n)://当前可用的许可数int availablePermits():

下面来看使用示例:

代码语言:javascript
复制
public class SemaphoreThreadDemo {    public static Semaphore semaphore = new Semaphore(5);
    static class ThreadDemo extends Thread {        @Override        public void run() {            try {                semaphore.acquire();                System.out.println(Thread.currentThread().getId() + "号线程在"+System.currentTimeMillis()+"获取资源");                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }finally {                semaphore.release();            }        }    }
    public static void main(String[] args) throws InterruptedException {        for (int i = 0; i < 30; i++) {            new ThreadDemo().start();        }    }
}

LockSupport

我们在 Hello,Thread生产者消费者模型 两篇文章中使用过wait和notify实现了线程之间的协作,其实关于线程协作JDK还为我们提供了另外一个工具类LockSupport。

使用LockSupport实现等待通知功能时还不需要获取锁哦

先来看一下LockSupport的常用方法:

代码语言:javascript
复制
// 禁用当前线程static void park()// 如果参数线程的不可用,则使其可用。static void unpark(Thread thread)

来看一下示例代码:

代码语言:javascript
复制
public class LockSupportThreadDemo {    public static Thread thread;    static class WaitThreadDemo extends Thread {        @Override        public void run() {            System.out.println("WaitThread wait,time=" + System.currentTimeMillis());            thread = Thread.currentThread();            LockSupport.park();            System.out.println("WaitThread end,time=" + System.currentTimeMillis());        }    }    static class NotifyThreadDemo extends Thread {        @Override        public void run() {            System.out.println("NotifyThread notify,time=" + System.currentTimeMillis());            LockSupport.unpark(thread);            try {                Thread.sleep(2000);            } catch (InterruptedException e) {                e.printStackTrace();            }            System.out.println("NotifyThread end,time=" + System.currentTimeMillis());        }    }    public static void main(String[] args) {        WaitThreadDemo waitThreadDemo = new WaitThreadDemo();        NotifyThreadDemo notifyThreadDemo = new NotifyThreadDemo();        waitThreadDemo.start();        try {            Thread.sleep(100);        } catch (InterruptedException e) {            e.printStackTrace();        }        notifyThreadDemo.start();    }}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java学习录 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档