摘要
Java高并发系列产品的开胃小菜,让我们再次品尝。这次,我们用2个线程同步的事例来引出Java.util.concurrent中的好多个高并发专用工具的使用方法。
正文
Java并发编程(二)怎样确保进程另外/更替实行
第一篇文章内容中,我就用怎样确保进程次序实行的事例做为Java高并发系列产品的开胃小菜。这篇大家仍然不容易有源代码剖析,只是用此外2个线程同步的事例来引出来Java.util.concurrent
中的好多个高并发专用工具的使用方法。
系列产品文章内容
Java并发编程(一)怎样确保进程次序实行 – 百度百家 (jianshu.com)
一、怎样确保好几个进程另外实行
确保好几个进程另外实行,指的是好几个进程在同一时间逐渐实行內部run()
方式 。
历经第一篇的学习培训,你应该能了解到,让进程能按大家的信念来运作实际上是必须用一些方式(信号量、高并发专用工具、线程池等)来完成的。常见的高并发专用工具一般有CountDownLatch、CyclicBarrier、Semaphore,这种专用工具在多线程编程中不可或缺。大家先看一下怎样用高并发专用工具确保进程另外实行吧。
1. 应用CountDownLatch完成
有关CountDownLatch
,count down的字面意思是到数,latch是锁上的含意。因此 CountDownLatch的意思便是到数闭店。大家看一下JDK8 API中是怎样表述的:
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
大约意思是,CountDownLatch
是一种同歩辅助软件,容许一个或好几个进程等候一组在别的进程中实行的实际操作进行以后再实行。
public class SimultaneouslyExample {
static CountDownLatch countDownLatch=new CountDownLatch(3);
public static void foo(String name) {
System.out.println("进程名:" name ",开始时间:" System.nanoTime());
try {
countDownLatch.await();
//2.每一次减一
countDownLatch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException{
Thread thread1 = new Thread(() -> foo("A"));
Thread thread2 = new Thread(() -> foo("B"));
Thread thread3 = new Thread(() -> foo("C"));
thread1.start();
thread2.start();
thread3.start();
Thread.sleep(300);
countDownLatch.countDown();
}
}
輸出結果:
进程名:A,开始时间:449768159780400
进程名:C,开始时间:449768159785200
进程名:B,开始时间:449768159795300
见到輸出結果,你很有可能会猜疑。本来A进程慢了4800纳秒啊,这不是同歩的。实际上没有必要感觉怪异,纳秒级的時间即便是JVM也没法那麼精确的把控,但是依据我的检测。这儿的同歩完成逻辑性能确保ms级的准确性。
2. 应用CyclicBarrier完成
另一种完成方法CyclicBarrier
,依据字面意思我能见到这个是一个可循环系统天然屏障。CyclicBarrier
能够 让一个或好几个进程抵达一个天然屏障点以后再运行。
话不多说,大家立即看一下编码中要怎么写:
public class CyclicBarrierExample{
private static CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
public static void foo(String name) {
System.out.println("进程名:" name ",开始时间:" System.currentTimeMillis());
try {
cyclicBarrier.await();
} catch (InterruptedException | BrokenBarrierException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws InterruptedException{
Thread thread1 = new Thread(() -> foo("A"));
Thread thread2 = new Thread(() -> foo("B"));
Thread thread3 = new Thread(() -> foo("C"));
thread1.start();
thread2.start();
thread3.start();
Thread.sleep(300);
}
}
輸出結果:
进程名:A,开始时间:1621232496385
进程名:B,开始时间:1621232496385
进程名:C,开始时间:1621232496385
二、怎样确保好几个进程更替实行
确保好几个进程更替实行,指的是好几个进程能够 依照一定的顺序逐渐实行內部run()
方式 。这儿大家必须应用Semaphore
高并发专用工具来完成。怎样你的高校专业学习过电脑操作系统得话,那麼你一定对信号量体制很了解
Semaphore(信号量):是一种电子计数器,用于维护一个或是好几个资源共享的浏览。假如进程要浏览一个資源就务必先得到信号量。假如信号量內部电子计数器超过0,信号量减1,随后容许共享资源这一資源;不然,假如信号量的电子计数器相当于0,信号量可能把进程嵌入休眠状态直到电子计数器超过0.当信号量应用完后,务必释放出来。Semaphore
的复位必须传到一个整形主要参数,此参数标志该信号量能够 占有的資源数量。比如大家有两个信号量A,B。A信号量能够 容许2个进程占有,B信号量容许一个进程占有,那麼复位的情况下Semaphore A = new Semaphore(2);
public class AlternateExample {
private static Semaphore s1 = new Semaphore(1);
private static Semaphore s2 = new Semaphore(1);
private static Semaphore s3 = new Semaphore(1);
static Semaphore[] signals = {s1, s2, s3};
public static void foo(int name) {
while (true) {
try {
signals[name - 1].acquire();
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("进程名:" name);
signals[(name) % 3].release();
}
}
public static void main(String[] args) throws InterruptedException {
Thread thread1 = new Thread(() -> foo(1));
Thread thread2 = new Thread(() -> foo(2));
Thread thread3 = new Thread(() -> foo(3));
//先占有1和2,这里我们要确保的次序是3、1、2
s1.acquire();
s2.acquire();
thread1.start();
thread2.start();
thread3.start();
Thread.sleep(300);
}
}
三、汇总
这篇大家用2个难题引出来了3个高并发专用工具CountDownLatch
、CyclicBarrier
、Semaphore
的具体运用的事例。下一篇大家讲从源代码视角深入分析下这三个专用工具的完成关键点。
参照文章内容
【详细编码】应用Semaphore完成进程的更替实行打印出 A1B2C三维4E5_学亮程序编写笔记-CSDNblog
CountDownLatch详细说明 – 百度百家 (jianshu.com)
Java中好几个进程更替循环系统实行 – 坐看云起时_雨宣 – 博客园 (cnblogs.com)
JAVA Semaphore详细说明 – 简单爱_wxg – 博客园 (cnblogs.com)
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
评论0