并发工具类

2020-02-01  本文已影响0人  JBryan
1.CountDownLatch

await(),进入等待的状态
countDown(),计数器减一
应用场景:启动三个线程计算,需要对结果进行累加。
CountDownLatch使用

package com.ljessie.sinopsis.util;

import java.util.concurrent.CountDownLatch;

/**
 * 等待所有线程都执行完毕之后,再执行
 * @author zbw
 *
 */
public class CountDownLatchDemo {

    public static void main(String[] args) {
        CountDownLatch countDownLatch = new CountDownLatch(8);
        //模拟裁判,等所有选手都完成比赛的情况下,才会继续进行
        new Thread() {
            public void run() {
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("800米比赛结束,清空跑道");
            }
        }.start();
        
        //模拟参赛运动员
        for (int i = 0; i < 8; i++) {
            int finalI = i;
            new Thread() {
                public void run() {
                    try {
                        Thread.sleep(finalI*1000);
                        System.out.println("到达终点:"+Thread.currentThread().getName());
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        //选手完成比赛
                        countDownLatch.countDown();
                    }
                }
            }.start();
        }
    }
}
2.CyclicBarrier--栅栏

允许一组线程相互等待达到一个公共的障碍点,之后再继续执行
跟countDownLatch的区别
CountDownLatch一般用于某个线程等待若干个其他线程执行完任务之后,它才执行;不可重复使用​ CyclicBarrier一般用于一组线程互相等待至某个状态,然后这一组线程再同时执行;可重用的

package com.ljessie.sinopsis.util;

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

/**
 * 等所有线程都到达某一状态时,再一起执行
 * @author zbw
 *
 */
public class CyclicBarrierDemo {
    
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(8);
        for (int i = 0; i < 8; i++) {
            int finalI = i;
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    
                    try {
                        Thread.sleep(finalI * 1000);
                        System.out.println("准备就绪:"+Thread.currentThread().getName());
                        barrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    System.out.println("起跑:"+Thread.currentThread().getName());
                }
            }).start();
            
        }
    }
}
3.Semaphore--信号量

控制并发数量
使用场景:接口限流

package com.ljessie.sinopsis.util;

import java.util.concurrent.Semaphore;

/**
 * 信号量,控制并发数量。
 * @author zbw
 *
 */
public class SemaphoreDemo {

    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(8);
        for (int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                
                @Override
                public void run() {
                    try {
                        semaphore.acquire();
                        System.out.println("开始执行:"+Thread.currentThread().getName());
                        Thread.sleep(5000); 
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        //线程执行完毕,释放资源
                        semaphore.release();
                    }           
                }
            }).start();
        }
    }
}

4.Exchanger--用于交换数据

它提供一个同步点,在这个同步点两个线程可以交换彼此的数据。这两个线程通过exchange方法交换数据, 如果第一个线程先执行exchange方法,它会一直等待第二个线程也执行exchange,当两个线程都到达同步点时,这两个线程就可以交换数据,将本线程生产出来的数据传递给对方。因此使用Exchanger的重点是成对的线程使用exchange()方法,当有一对线程达到了同步点,就会进行交换数据。因此该工具类的线程对象是【成对】的。

package com.ljessie.sinopsis.util;

import java.util.concurrent.Exchanger;

/**
 * 用来交换数据的,两个线程通过exchange方法交换数据,如果第一个线程先
 * 执行exchange方法,它会一直等待第二个线程也执行exchange方法。
 * 将本线程生产的数据交换给对方。
 * @author zbw
 *
 */
public class ExchangerDemo {
    
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<String>();
        String str1 = "zbw";
        String str2 = "jessie";
        
        new Thread(new Runnable() {
            
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"初始值------>"+str1);
                try {
                    String exchangeString = exchanger.exchange(str1);
                    System.out.println(Thread.currentThread().getName()+"交换后------>"+exchangeString);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
        new Thread(new Runnable() {     
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName()+"初始值------>"+str2);
                try {
                    Thread.sleep(2000);
                    String exchangeString = exchanger.exchange(str2);
                    System.out.println(Thread.currentThread().getName()+"交换后------>"+exchangeString);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }   
                        
            }
            }).start();
    }

}
上一篇 下一篇

猜你喜欢

热点阅读