码迷,mamicode.com
首页 > 其他好文 > 详细

juc包下四大并发工具

时间:2019-08-08 00:25:54      阅读:108      评论:0      收藏:0      [点我收藏+]

标签:getname   生产   阻塞   http   thread   信号   util   col   com   

juc.CountDownLatch 闭锁

一个线程在等待一组线程后再恢复执行

await()等待其他线程执行完毕

被等待线程执行完毕后计数器-1

如何知道其他线程执行完了?

计数器,若一组线程为,CountDown为5,减到0代表等待线程被全部执行完毕

一次性工具:当Countdown的值减到0的时候再也无法恢复

 

juc内部的代码都是lock体系来实现的

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;


// 运动员线程
class CDLTask implements Runnable {
    private CountDownLatch countDownLatch;

    public CDLTask(CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"开始跑步");
        try {
            TimeUnit.SECONDS.sleep(1);
            System.out.println(Thread.currentThread().getName()+"到达终点");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


public class CountDownLatchDemo {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(4);
        CDLTask cdlTask = new CDLTask(countDownLatch);
        System.out.println("比赛开始...");
        new Thread(cdlTask,"运动员A").start();
        new Thread(cdlTask,"运动员B").start();
        new Thread(cdlTask,"运动员C").start();
        new Thread(cdlTask,"运动员D").start();
        // 等待所有线程都到达终点后再输出此语句
        countDownLatch.await();
        System.out.println("比赛结束...");
    }
}

技术图片

 


juc.CyclicBarrier  循环栅栏

一组线程同时到达临界点后再恢复执行(先到达临界点的线程会阻塞,直到所有线程都到达临界点)

public CyclicBarrier(int parties, Runnable barrierAction)

当多个线程同时到达临界点时,

随机挑选一个线程执行barrierAction后再同时恢复执行

计数器的值可以恢复

await

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.TimeUnit;

class CBTask implements Runnable {
    private CyclicBarrier cyclicBarrier;

    public CBTask(CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
    }

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+
                "正在写入数据...");
        try {
            TimeUnit.SECONDS.sleep(2);
            System.out.println(Thread.currentThread().getName()+
                    "写入数据完毕,等待其他线程写入完毕...");
            cyclicBarrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
        System.out.println("所有线程均已写入完毕,继续恢复执行...");
    }
}
class CyclicBarrierDemo {
    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4
                ,() -> {
            System.out.println("当前线程为:"+Thread.currentThread().getName());
        });
        CBTask cbTask = new CBTask(cyclicBarrier);
        for (int i = 0; i < 4; i++) {
            new Thread(cbTask,"写线程"+(i+1)).start();
        }
    }
}

技术图片

 


juc.Exchanger 线程交换器

用于两个线程直线的数据交换,当Exchanger只有一个线程时,该线程会阻塞直到有别的线程
调用exchange进入缓冲区,当前线程与新线程交换数据后同时恢复执行。
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;


class ExchangerDemo {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<>();
        Thread girlThread = new Thread(() -> {
            try {
                String girl = exchanger.exchange("我喜欢你.....");
                System.out.println("女生说:"+girl);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        girlThread.start();
        Thread boyThread = new Thread(() -> {
            System.out.println("女神缓缓步入眼帘...");
            try {
                TimeUnit.SECONDS.sleep(1);
                String boy = exchanger.exchange("我喜欢你!");
                System.out.println("男生说:"+boy);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        boyThread.start();
    }
}

技术图片

 



juc.Semaphore 信号量

acquire() : 尝试占用一个信号量,失败的线程会阻塞直到有新的信号量

release() : 释放一个信号量

acquire(int n) : 尝试占用n个信号量,失败的线程会阻塞直到有新的信号量

release(int n) : 释放n个信号量

 

import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;


class SemaphoreTask implements Runnable {
    private Semaphore semaphore;

    public SemaphoreTask(Semaphore semaphore) {
        this.semaphore = semaphore;
    }

    @Override
    public void run() {
        try {
            semaphore.acquire(2);
            System.out.println(Thread.currentThread()
                    .getName()+"占用2台设备生产");
            TimeUnit.SECONDS.sleep(2);
            System.out.println(Thread.currentThread()
                    .getName()+"生产完毕,释放设备");
            semaphore.release(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
class SemaphoreDemo {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(5);
        SemaphoreTask task = new SemaphoreTask(semaphore);
        for (int i = 0; i < 8; i++) {
            new Thread(task,"工人"+(i+1)).start();
        }
    }
}

技术图片

 

juc包下四大并发工具

标签:getname   生产   阻塞   http   thread   信号   util   col   com   

原文地址:https://www.cnblogs.com/hetaoyuan/p/11317029.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!