java多线程之闭锁(CountDownLatch)、同步屏幕(CyclicBarrier)、信号量(Semaphore)

时间:2021-02-18 18:15:42

闭锁CountDownLatch

若有多条线程,其中一条线程需要等到其他所有线程准备完所需的资源后才能运行,这样的情况可以使用闭锁。

import java.util.concurrent.CountDownLatch;

/**
* Created by chenjianan on 2017/1/17-15:11.
* <p>
* Describe: CountDownLatch 闭锁练习,
* 使用场景:若有多条线程,其中一条线程要等其他线程执行完才能执行,那么可以用闭锁;
* 闭锁只会阻塞一条线程,目的是为了让该条任务线程满足条件后执行;
*/

public class CountDownLatchTest {


public void test(){


CountDownLatch latch=new CountDownLatch(2);//初始化闭锁,并设置资源数目

new Thread(new Runnable() {
@Override
public void run() {
try {
// 本线程必须等待所有资源加载完后才能执行
latch.await();
// 当闭锁数量为0时,await返回,执行接下来的任务
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程3执行。。。。");
}
}).start();



new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程2执行。。。。");
System.out.println("线程2执行。。。。"+latch.getCount());
// 本资源加载完后,闭锁-1
latch.countDown();
System.out.println("线程2执行。。。。"+latch.getCount());
}
}).start();

new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程1执行。。。。");
System.out.println("线程1执行。。。。"+latch.getCount());
// 本资源加载完后,闭锁-1
latch.countDown();
System.out.println("线程1执行。。。。"+latch.getCount());
}
}).start();

}


public static void main(String[] args){
new CountDownLatchTest().test();
}
}


//执行结果
线程2执行。。。。
线程2执行。。。。2
线程2执行。。。。1
线程1执行。。。。
线程1执行。。。。1
线程1执行。。。。0
线程3执行。。。。

CyclicBarrier 同步屏幕


import java.util.concurrent.CountDownLatch;

/**
* Created by chenjianan on 2017/1/17-15:11.
* <p>
* Describe: CountDownLatch 闭锁练习,
* 使用场景:若有多条线程,其中一条线程要等其他线程执行完才能执行,那么可以用闭锁;
* 闭锁只会阻塞一条线程,目的是为了让该条任务线程满足条件后执行;
*/

public class CountDownLatchTest {


public void test(){


CountDownLatch latch=new CountDownLatch(2);//初始化闭锁,并设置资源数目

new Thread(new Runnable() {
@Override
public void run() {
try {
// 本线程必须等待所有资源加载完后才能执行
latch.await();
// 当闭锁数量为0时,await返回,执行接下来的任务
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程3执行。。。。");
}
}).start();



new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程2执行。。。。");
System.out.println("线程2执行。。。。"+latch.getCount());
// 本资源加载完后,闭锁-1
latch.countDown();
System.out.println("线程2执行。。。。"+latch.getCount());
}
}).start();

new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程1执行。。。。");
System.out.println("线程1执行。。。。"+latch.getCount());
// 本资源加载完后,闭锁-1
latch.countDown();
System.out.println("线程1执行。。。。"+latch.getCount());
}
}).start();

}


public static void main(String[] args){
new CountDownLatchTest().test();
}
}


//执行结果
线程1执行。。。。await
线程2执行。。。。await
线程3执行。。。。await
到达屏幕后执行的任务、。。
线程3执行。。。。await
线程1执行。。。。await
线程2执行。。。。await

信号量Semaohore


/**
* Created by chenjianan on 2017/1/17-17:06.
* <p>
* Describe: 信号量
* 使用场景
* 若有m个资源,但有n条线程(n>m),因此同一时刻只能允许m条线程访问资源,此时可以使用Semaphore控制访问该资源的线程数量。
*/

public class SemaphoreTest {
public void test() {
// 创建信号量对象,并给予3个资源
Semaphore semaphore = new Semaphore(3);

// 开启10条线程
for (int i = 0; i < 10; i++) {

new Thread(new Runnable() {
@Override
public void run() {
try {
// 获取资源,若此时资源被用光,则阻塞,直到有线程归还资源
semaphore.acquire();
System.out.println("执行任务"+ Thread.currentThread().getName());
System.out.println("释放资源"+ Thread.currentThread().getName());
// 释放资源
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();

}

}

public static void main(String[] args){
new SemaphoreTest().test();
}
}