1.信号量Semaphore: 像synchronized, ReentrantLock等这些对临界区资源进行同步后,所有对临界区资源进行访问的线程都得串行排队,而信号量允许指定的线程数同时进行访问
demo:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;
public class TestSemaphore implements Runnable{
private static Semaphore semaphore = new Semaphore(5); //允许同时5个线程进行访问 不会阻塞
@Override
public void run(){
try {
semaphore.acquire();
System.out.println(System.currentTimeMillis() +" "+ Thread.currentThread().getName());
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
}
public static void main(String[] args){
ExecutorService executorService = Executors.newFixedThreadPool(20);
TestSemaphore testSEmaphore = new TestSemaphore();
for(int i = 0; i < 20; i++){
executorService.submit(testSEmaphore);
}
executorService.shutdown(); //关闭连接池 否则程序不会退出
}
}
结果显示:
1578281162342 pool-1-thread-1
1578281162342 pool-1-thread-5
1578281162352 pool-1-thread-4
1578281162352 pool-1-thread-8
1578281162352 pool-1-thread-2
1578281165347 pool-1-thread-3
1578281165347 pool-1-thread-10
1578281165357 pool-1-thread-9
1578281165357 pool-1-thread-6
1578281165357 pool-1-thread-7
1578281168351 pool-1-thread-12
1578281168351 pool-1-thread-11
1578281168361 pool-1-thread-13
1578281168361 pool-1-thread-14
1578281168361 pool-1-thread-15
1578281171354 pool-1-thread-16
1578281171354 pool-1-thread-17
1578281171364 pool-1-thread-18
1578281171364 pool-1-thread-19
1578281171364 pool-1-thread-20
可以发现: 五个线程一波,分批次进行
2.读写锁 ReadWriteLock: 特点 : 对同一临界区资源进行访问的线程.如果已经有写线程占用锁,读线程和写线程需要等待;如果有读线程占有锁,写线程需要等待,读线程不需要等待
demo:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class TestReadWriteLock{
static ReentrantLock lock = new ReentrantLock();
static ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
static ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock(); //可以看出 读锁 是 读写锁内部的锁
static ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock(); //可以看出 写锁 是 读写锁内部的锁
static int i;
private void handleRead(Lock lock){
lock.lock();
try {
System.out.println(System.currentTimeMillis() +" "+ Thread.currentThread().getName()+ " " + i);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
private void handleWrite(Lock lock, int i){
lock.lock();
try {
this.i = i;
System.out.println(System.currentTimeMillis() + " " + Thread.currentThread().getName());
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
lock.unlock();
}
}
public static void main(String[] args){
TestReadWriteLock testReadWriteLock = new TestReadWriteLock();
for(int i = 0; i < 18; i++){
new Thread(new Runnable() {
@Override
public void run() {
testReadWriteLock.handleRead(readLock);
// testReadWriteLock.handleRead(lock);
}
}).start();
}
for(int i = 18; i < 20; i++){
new Thread(new Runnable() {
@Override
public void run() {
testReadWriteLock.handleWrite(writeLock, 10);
// testReadWriteLock.handleWrite(lock, 10);
}
}).start();
}
}
}
结果显示:
1578294290002 Thread-2 0
1578294290005 Thread-9 0
1578294290005 Thread-0 0
1578294290005 Thread-10 0
1578294290005 Thread-4 0
1578294290006 Thread-1 0
1578294290006 Thread-15 0
1578294290007 Thread-3 0
1578294290007 Thread-6 0
1578294290007 Thread-7 0
1578294290007 Thread-11 0
1578294290009 Thread-8 0
1578294290010 Thread-12 0
1578294290010 Thread-13 0
1578294290010 Thread-5 0
1578294290011 Thread-16 0
1578294290012 Thread-17 0
1578294290012 Thread-14 0
1578294293012 Thread-19
1578294295012 Thread-18
可以看出 读线程 运行的很快,没有停顿;最后两个线程的出现都会停顿两秒再显示
3.计数器CountDownLatch:
计数器会指定线程数量num,程序会等待num个线程都执行完成才往下继续执行 .否则一直等待
demo:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestCountDownLatch{
private static CountDownLatch countDownLatch = new CountDownLatch(2); //计数器指定数量
private static class WorkThread implements Runnable{
@Override
public void run(){
try {
Thread.sleep(1000);
System.out.println("hard working...");
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown(); //该程序完成
}
}
private static class StudyThread implements Runnable{
@Override
public void run(){
try {
Thread.sleep(1000);
System.out.println("hard study ....");
} catch (InterruptedException e) {
e.printStackTrace();
}
countDownLatch.countDown(); //该程序完成
}
}
public static void main(String[] args) throws InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(10);
executorService.submit(new WorkThread());
executorService.submit(new StudyThread());
countDownLatch.await(); //开始等待
System.out.println("走向人生巅峰...");
executorService.shutdown();
}
}
结果显示:
hard working...
hard study ....
走向人生巅峰...
如果计数器指定的个数大于2,则一直等待下去;如果小于0,运行会抛出;如果等于1,则一个线程结束主线程就执行
4.循环栅栏CycliBarrier:
循环栅栏,顾名思义就是障碍物.所有共用这个栅栏中的每个线程都得等待,知道所有线程都等待,则往下执行;循环栅栏可以多次使用
demo:
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class TestCyclicBarrier implements Runnable{
private static CyclicBarrier cyclicBarrier;
private static String msg;
public TestCyclicBarrier (CyclicBarrier cyclicBarrier){
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run(){
try {
cyclicBarrier.await(); //每个线程在此都会等待 除非所有线程(循环栅栏规定的数量)都到了这里 则运行BarrierRun
System.out.println(Thread.currentThread().getName() + "干活中....");
cyclicBarrier.await(); //每个程序员干完活 在此等待 每个程序员都干完活 则运行BarrierRun
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace(); //如有一个线程发生异常或者中断 抛出错误之后 其他线程就会发生此异常
}
}
private static class BarrierRun implements Runnable{
@Override
public void run(){
if("0".equals(msg)){
System.out.println("所有程序员都干完活了");
}else{
System.out.println("所有程序员集合完毕");
msg = "0";
}
}
}
public static void main(String[] args){
CyclicBarrier cyclicBarrier = new CyclicBarrier(10, new BarrierRun());
for(int i = 0; i < 10; i++){
System.out.println("程序员" + i + "集合");
new Thread(new TestCyclicBarrier(cyclicBarrier)).start();
}
}
}
结果显示:
程序员0集合
程序员1集合
程序员2集合
程序员3集合
程序员4集合
程序员5集合
程序员6集合
程序员7集合
程序员8集合
程序员9集合
所有程序员集合完毕
Thread-8干活中....
Thread-0干活中....
Thread-2干活中....
Thread-9干活中....
Thread-3干活中....
Thread-6干活中....
Thread-4干活中....
Thread-1干活中....
Thread-5干活中....
Thread-7干活中....
所有程序员都干完活了
---- 来源于Java高并发程序涉及
来源:CSDN
作者:欣淡定
链接:https://blog.csdn.net/xindanding/article/details/103854191