CountDownLatch、CyclicBarrier、Semaphore讲解

举报
Studying-swz 发表于 2022/10/26 19:17:16 2022/10/26
【摘要】 这三个也是面试常问的,作为线程通信的方法 1.CountDownLatch(CDL)主要是用于一个线程等待其他完成后才继续执行。主要方法:await()、countDown()CountDownLatch cdl = new CountDownLatch(2);//第一个线程new Thread(){ public void run(){ System.out.println("11111...

这三个也是面试常问的,作为线程通信的方法

1.CountDownLatch(CDL)

主要是用于一个线程等待其他完成后才继续执行。

  • 主要方法:await()、countDown()
CountDownLatch cdl = new CountDownLatch(2);

//第一个线程
new Thread(){
	public void run(){
		System.out.println("1111111");
		cdl.countDown();
	}
}.start();
//第二个线程
new Thread(){
	public void run(){
		System.out.println("22222222222221111111");
		cdl.countDown();
	}
}.start();

//主线程
cdl.await();
System0out.println("main执行!!!!!");

2.CyclicBarrier

回环栅栏:主要是用于多个线程在某个点/状态同时执行。

  • 主要方法:await()
int N = 4;
CyclicBarrier cb = new CyclicBarrier(N);
for(int i=0;i<N;i++){
	new Thread(){
		@Override
		public void run(){
			System.out.println(Thread.currentThread().getName() + "--------");
			cb.await();
			System.out.println(Thread.currentThread().getName() + "after-------");
		}
	}
}

注:其await(long timeout,TimeUnit unit)重载方法,让已到达的线程等待至一定的时间,如果还没有到达指定的数量,则这些开始执行。

3.Semaphore

信号量:主要控制访问临界资源的线程数量

  • 主要方法:acqurie()、release()
//工人数
int N = 8;
//机器或者说是资源数
Semaphore sp = new Semaphore (5);
for(int i=0;i<N;i++){
	new Thread(){
		@Override
		public void run(){
			sp.acquire();
			System.out.println("获取机器成功!!");
			sp.release();
			System.out.println("释放机器!!");
		}
	}
}

总结:
前两者主要是实现线程之间的等待,而semaphore主要是控制对资源的访问

4.生产者、消费者

开始撸代码了:

4.1 Synchronized


public class MyTest01 {


    public class Data{
        private  int num = 0;
        public synchronized void product() throws InterruptedException {
            while(num!=0){
                this.wait();
            }
            num++;
            System.out.println("生产一个!");
            this.notify();
        }
        public synchronized void consume() throws InterruptedException {
            while(num==0){
                this.wait();
            }
            num--;
            System.out.println("消费一个!");
            this.notify();
        }
    }
     @Test
    public void test(){
        final Data data = new Data();
        //final DataLock data = new DataLock();
        //生产者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.product();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //消费者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.consume();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }
}

4.2 ReentrantLock


public class MyTest01 {


     public class DataLock{
        private  int num = 0;
        ReentrantLock lock = new ReentrantLock();
        Condition cd = lock.newCondition();
        //Condition cd2 = lock.newCondition();

        public  void product() throws InterruptedException {
            lock.lock();
            while(num!=0){
                cd.await();
            }
            num++;
            System.out.println("生产一个!");
            cd.signalAll();
            lock.unlock();
        }
        public void consume() throws InterruptedException {
            lock.lock();
            while(num==0){
                cd.await();
            }
            num--;
            System.out.println("消费一个!");
            cd.signal();
            lock.unlock();
        }
    }
    
     @Test
    public void test(){
        //final Data data = new Data();
        final DataLock data = new DataLock();
        //生产者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.product();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();
        //消费者
        new Thread(){
            public void run(){
                for(int i = 0;i<5;i++){
                    try {
                        data.consume();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }.start();

    }
}

参考链接:
https://blog.csdn.net/jike11231/article/details/112792709

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。