CountDownLatch

CountDownLatch主要有两个方法,countDown()和await()方法,在创建CountDownLatch对象时候,初始值与调用countDown()次数相等后,调用await()方法的线程才会运行,这样就可以主线程在别的线程执行完了后,才结束。

使用场景:可以分别创建新的线程单独处理一个子任务,当全部的子任务都处理完毕后,主线程进行汇总,各个分线程调用一次countDown()方法,主线程调用await()方法。

import java.util.concurrent.CountDownLatch;

public class CountDownLatchTest {
    
    private static final Integer SIZE = 5;
    
    public static void main(String[] args) {

        CountDownLatch countDownLatch = new CountDownLatch(SIZE);
        for (int i = 0; i < SIZE; i++) {
            MyselfThread myselfThread = new MyselfThread("num"+i,countDownLatch);
            myselfThread.start();
        }
        try {
            countDownLatch.await(); //主线程始终在创建的MyselfThread运行完毕后才会执行完毕
            System.out.println("main thread end");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class MyselfThread extends Thread {

    private CountDownLatch countDownLatch;
    private String name;

    public MyselfThread(String name, CountDownLatch countDownLatch) {
        this.countDownLatch = countDownLatch;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            System.out.println(this.name + " start");
            Thread.sleep(1000);
            System.out.println(this.name + " end");
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

image.png

CyclicBarrier

CyclicBarrier主要有await()和reset()方法,当调用await()方法的线程数目与CyclicBarrier初始线程值相同时,所有线程才可进行下面程序,reset()方法,可以修改构造函数中的初始值,CountDownLatch不能重置。

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

public class CyclicBarrierTest {

    private static final Integer SIZE = 5;

    public static void main(String[] args) {
        CyclicBarrier cyclicBarrier = new CyclicBarrier(SIZE);

        for (int i=0;i<SIZE;i++){
            MyOneThread myOneThread = new MyOneThread("num " + i,cyclicBarrier);
            myOneThread.start();
        }
    }
}

class MyOneThread extends Thread {

    private CyclicBarrier cyclicBarrier;
    private String name;

    public MyOneThread(String name, CyclicBarrier cyclicBarrier) {
        this.cyclicBarrier = cyclicBarrier;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(1000);
            System.out.println(this.name + " start"); //所有线程都到达此处时候,才会进行下面程序
            cyclicBarrier.await();
            Thread.sleep(1000);
            System.out.println(this.name + " end");
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}

image.png

Semaphere

Semphere可控制运行中线程的数目,通过acquire()方法进入,release()方法退出。

使用场景:可以控制资源的访问限制,例如数据库连接只有10个,当多个线程都获取数据库连接的时候就可以通过Semaphere进行控制

import java.util.concurrent.Semaphore;

public class SemaphoreTest {
    public static void main(String[] args) {
        Semaphore semaphore = new Semaphore(2);
        for (int i=0;i<5;i++){
            new Thread(()->{
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName() + " start");
                    Thread.sleep(1000);
                    System.out.println(Thread.currentThread().getName() + " end");
                    semaphore.release();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

image.png

Exchange

Exchange用于两个线程交换数据,不能用于多个线程之间交换数据。

import java.util.concurrent.Exchanger;

public class ExchangeTest {
    public static void main(String[] args) {
        Exchanger<String> exchanger = new Exchanger<>();

        Thread left = new Thread(()->{
            try {
                String result = exchanger.exchange("left tell right : I give you 100");
                System.out.println("left Thread get : "+ result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        left.start();
        Thread right = new Thread(()->{
            try {
                String result = exchanger.exchange("right tell left : I give you 300");
                System.out.println("right Thread get : "+ result);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
        right.start();
    }
}

image.png


你若安好便是晴天
82 声望10 粉丝

« 上一篇
java 线程池
下一篇 »
ForkJoinPool使用