并发工具类

Posted liuying23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了并发工具类相关的知识,希望对你有一定的参考价值。

1.并发工具类
1.CountDownLatch:可以实现线程计数,阻塞后续线程
        CountDownLatch类位于java.util.concurrent包下,利用它可以实现类似计数器的功能。比如有一个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。
countDown()实现计数器-1
await()等待拦截方法,等待计数器为0时再放行,否则则一直阻塞
getCount()获取当前计数器中计数数量

案例: 

      

/**
* 等待子线程全部执行完毕之后再执行主线程内容
* @param args
*/
private static CountDownLatch countDownLatch=new CountDownLatch(2);
public static void main(String[] args) throws InterruptedException {
System.out.println("======主线程开始运行=====");
//第一个子线程
new Thread(()->{
System.out.println("子线程"+Thread.currentThread().getName()+"开始运行~");
//线程数量-1操作,通知该线程运行完毕
countDownLatch.countDown();
}).start();

//第二个子线程
new Thread(()->{
System.out.println("子线程"+Thread.currentThread().getName()+"开始运行~");
//线程数量-1操作,通知该线程运行完毕
countDownLatch.countDown();
}).start();

//等待,等待计数器中线程计数为0时才继续向下执行
countDownLatch.await();
System.out.println("子线程执行完毕,主线程继续执行");

 

//获取当前计数线程数量
/*while (true){
if(countDownLatch.getCount()==0){
System.out.println("子线程执行完毕,主线程继续执行");
break;
}
}*/
}

 





2.CyclicBarrier:类似于栅栏,进行拦截,等待所有线程都准备,然后统一放行,阻塞当前线程
          

//设置等待线程数量,当线程数量到达指定数量时,统一向下运行
private static CyclicBarrier cyclicBarrier=new CyclicBarrier(10);
public static void main(String[] args) {
//创建10个线程
for (int i = 1; i <=10 ; i++) {
new Thread(()->{
try {
Thread.sleep(100);
System.out.println(Thread.currentThread().getName()+"准备就绪");
//等待
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"开始比赛~");
}).start();
}
}

 


3.Semaphore:可以做资源控制,容器中有几个资源,那么线程执行时先申请资源,资源如果可用则继续执行,如果资源不可用则阻塞等待当资源占用完毕之后将该资源释放,其他线程排队占用
       

private static Semaphore semaphore=new Semaphore(3);
public static void main(String[] args) {
for (int i = 1; i <=10 ; i++) {
new Thread(()->{
try {
//申请资源,发生阻塞
System.out.println(Thread.currentThread().getName()+"申请茅坑~");
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+"可以安心上厕所了");
//模拟上厕所时间
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"舒服,上完了~");
//释放资源
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}

 


     
4.Exchanger:可以执行线程的资源交换,线程数量必须为偶数,因为是两两相互交换资源,如果不是偶数默认情况下导致阻塞,可以设置交换资源超时时间

     

public class ExchangerDemo {
private static String str1="资源1";
private static String str2="资源2";
//构建资源交换对象
private static Exchanger<String> stringExchanger=new Exchanger<>();
public static void main(String[] args) {
//第一个线程
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"初始占用资源:"+str1);
//资源交换,将资源交给其他线程和获取到其他线程交换过来的资源
try {
String newStr = stringExchanger.exchange(str1);
System.out.println(Thread.currentThread().getName()+"交换资源:"+newStr);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();

//第二个线程
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"初始占用资源:"+str2);
//资源交换,将资源交给其他线程和获取到其他线程交换过来的资源
try {
String newStr = stringExchanger.exchange(str2);
System.out.println(Thread.currentThread().getName()+"交换资源:"+newStr);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();

//第三个线程
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"初始占用资源:"+str2);
//资源交换,将资源交给其他线程和获取到其他线程交换过来的资源
try {
//设置资源交换超时时间
String newStr = stringExchanger.exchange(str2,1000, TimeUnit.MILLISECONDS);
System.out.println(Thread.currentThread().getName()+"交换资源:"+newStr);
} catch (InterruptedException | TimeoutException e) {
e.printStackTrace();
}
}).start();
}
}

 

以上是关于并发工具类的主要内容,如果未能解决你的问题,请参考以下文章

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段

elasticsearch代码片段,及工具类SearchEsUtil.java

solr分布式索引实战分片配置读取:工具类configUtil.java,读取配置代码片段,配置实例

golang goroutine例子[golang并发代码片段]

并发工具类

java中并发常用工具类及示例代码