好喜欢你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的功效与作用

频道:欧洲联赛 日期: 浏览:150

导言

在JDK的并发包里供给了许多有意思的并发东西类。CountDownLatch、CyclicBarrier和Semaphore 东西类供给了一种并发流程操控的手法,Exchanger 东西类则供给了在线程间交流数据的一种手法。

CountDownLatch

CountDownLatch答应一个或多个线程等候其他线程完结操作。

其实最简略的做噶是运用join()办法,join用于让当时履行线程等候join线程履行完毕。其完结原理是不断检查join线程是否存活,假如join线程存活则让当时线程永久等候。其间,wait(0) 表明永久等候下去,代码片段如下:

while (isAlive()) {
wait(0);
}

知道线程间断后,线程的 this.notifyAll() 办法被调用,调用 notifyAll() 办法是在 JVM里完结的,所好喜爱你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的成效与效果以在JDK里看不到,咱们能够检查JVM源码。

在JDK1.5之后的并发包CountDownLatch也能够完结join的功用,而且功用更多,更省人民医院眼科王丽娅强壮。

示例代码80it电脑网:

public static void main(String[] args) throws InterruptedException {
CountDownLatch c = new CountD缚魂ownLatch(2);
new Thread(new Runnable() {
@O金艺彬verride
public void run() {
System.out.println(1);
c.countDown();
System.out.println(2);
c.countDown();//注释这行
}
}).start();
c.await();
System.out.println("3");
}

运转成果:

1
2
3

CountDownLatch的结构办法接纳一个int类型的参数作为计数器,假如你想等候N个点完结,这儿就传入N。

当咱们调用CountDownLatch的countDown()办法时,N就会减1,CountDownLatch的 await() 办法会堵塞当时线程,直到N变成零。由于countDown()办法能够用在任何地方,所以这儿说的N个点,也能够是N个线程。用在多个线程时,你只需求把这个CountDownLatch的引证传递到线程里。

假如有某个线程处理的比较慢,咱们不行能让主线程一向等候,所以咱们能够运用别的一个带指定时刻的await办法,await(long time, TimeUnit unit), 这个办法等候特定时刻后,就会不再堵塞当时线程。join也有相似的办法。

留意兽妃逐个天才召唤师:计数器有必要大于等于0,仅仅等于0时分,计数器便是零,调用await办法时不会堵塞当时线程。CountDownLatch不行能从头初始化或许修正CountDownLatch目标的内部计数器的值。一个线程调用countDown办法 happen-before 别的一个线程调用await办法。

CyclicBarrier

CyclicBarrier 的字面意思是可循环运用(Cyclic)的屏障(Barrier)。它要做的作业是,让一组线程抵达一个屏障(也能够叫同步点)时被堵塞,直到最终一个线程抵达屏障时,屏障才会开门,一切被屏障阻拦的线程才会持续运转。

1 结构办法

CyclicBarrier默许的结构办法是CyclicBarrier(int parties),其参数表明屏障阻拦的线程数量,每个线程调用await办法通知CyclicBarrier我现已抵达了屏障,然后当时线程被堵塞。

示例代码:

 public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
CyclicBarrier c = new CyclicBarrier(2);
new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printSt愚泉记ackTrace();
}
System.out.println("1");
}
}).start();
c.await();
System.out.println(2);
}

运转成果:

1
2

或许

2
1

假如把new CyclicBarrier(2)修正成new CyclicBarrier(3)则主线程和子线程会永久等候,由于没有第三个线程履行await办法,即没有第三个线程抵达屏障,所以之前抵达屏障的两个线程都不会持续履行


CyclicBarrier还供给一个更高档的结构函数CyclicBarrier(int parties, Runnable barrierAction),用于在线忽必烈改制程抵达屏障时,优先履行barrierAction,便利处理更杂乱的事务场景。

示例代码:

 public static void main(String[] args) throws BrokenBarrierException, InterruptedException {
CyclicBarrier c = new CyclicBarrier(2, new Runnab唐慧女儿案le() {
@Override
public void run() giga5{
System.out.println(3);
}
});
new Thread(new Runnable() {
@Override
public void run() {
try {
c.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
System.out.println("1");
}
}).start();
c.await();
System.o好喜爱你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的成效与效果ut.pr好喜爱你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的成效与效果intln(2);
}

运转成果:

3
1
2

2 运用场景

CyclicBarrier能够用于多线程核算数据,最终兼并核算成果的运用场景。比方咱们用一个Excel保好喜爱你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的成效与效果存了用户一切银行流水,每个Sheet保存一个帐户近一年的每笔银行流水,现在需求核算用户的日均银行流水,先用多线程处理每个sheet里的银行流水,都履行完之后,得到毛岸红简历每个sheet的日均银行流水,最终,再用barrierAction用这些线程的核算成果,核算出整个Excel的日均银行流水。

2.3 CyclicBarrier和CountDownLatch的差异

CountDownLatch的计数器只能运用一次。而CyclicBarrier的计数器能够运用reset() 办法重置。所以CyclicBarrier能处理更为杂乱的事务场景,例如,假如核算发作过错,能够重置计数器,并让线程们从头履行一次。

CyclicBarrier还供给其他有用的办法,比方getNumberWaiting办法能够获得CyclicBarrier堵塞的线程数量。isBroken办法用来知道堵塞的线程是好喜爱你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的成效与效果否被中止。

示例代码:

 public static void main(String[] args){
CyclicBarrier c = new CyclicBarrier(2);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
try {
c.aw姜异康最新去向ait();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
});
t.start();
t.interrupt();
try {
c.await();
} cat好喜爱你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的成效与效果ch (InterruptedException e) {
// e.printStackTrace();
} catch (BrokenBarrierException e) {
// e.printStackTrace();
}finally {
System.out.println(c.isBroken());
}
}

运转成果:

true

Semaphore

1 效果

Semaphore(信号量)是用来操控一起拜访特定资源的线程数量,它经过和谐各个线程,以确保合理的运用公共资源。

2 简介

Semaphore也是一个线程同步的辅佐类,能够保护当时拜访本身的线程个数,并供给了同步机制。运用Semaphore能够操控一起拜访资源的线程个数,例如,完结一个文件答应的并发拜访数。

3 运用场景

Semaphore能够用于做流量操控,特别共用资源有限的运用场景,比方数据库衔接。假如有一个需求,要读取几万个文件的数据,由于都是IO密集型使命,咱们能够发动几十个线程并发的读取,可是假如读到内存后,还需求存储到数据库中,而数据库的衔接数只要10个开国将军任荣谢世,这时咱们有必要操控只要十个线程一起获取数据库衔接保存数据,不然会报错无法获取数据库衔接。这个时分,咱们就能够运用Semaphore来做流控,代码如下:

public static void main(String[] args) {
final int THREAD_NUM = 30;
ExecutorService threadPool = Executors.newFixedThreadP大吴哥凶恶漫画大全ool(THREAD_NUM);
Semaphore s = new Semaphore(10);//只答应10个线程并发履行
for (int i = 0; i < THREAD_NUM; i++) {
threadPool.execute(wangyuyunnew Runnable() {
@Override
public void run() {
try {
s.acquire();
System.out.println("play");
s.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
threadPool.shutdown();
}

在代码中,虽然有30个线程在履行,可是只答应10个并发的履行。石纯子李晨Semaphore的结构办法Semaphore(int permits) 承受一个整型的数字,表明可用的许可证数量。Semaphore(10)表明答应10个线程获取许可证,也便是最大并发数是10。Semaphore的用法也很简略,首要线程运用Semaphore的acquire()获取一个许可证,运用完之后调用release()偿还许可证。还能够用tryAcquire()办法测验获陀枪儿媳取许可证。

4 其他办法

Semaphore还供给一些其他办法:

  • int availablePermits() :回来此信号量中当时可用的许可证数。
  • int getQueueLength():回来正在等候获取许可证的线程数。
  • boolean hasQueuedThreads() :是否有线程正在等候获取许可证。
  • void reducePermits(int reduction) :削减reduction个许可证。是个protected办法。
  • Collection getQueuedThreads() :回来一切等候获取许可证的线程调集。是个protected办法。

Exchanger

Exchanger(交流者)是一个用于线程间协作的东西类。Exchanger用于进行线程间的数据交流。它供给一个同步点,在这个同步点两个线程能够交流互相的数据。这袁政益两个线程经过exchange办法交流数据, 假如第一个线程先履行exchange办法,它会一向等候第二个线程也履行exchange,当两个线程都抵达同步点时,这两个线程就能够交流数据,将本线程出产出来的数据传递给对方。

运用场景

1、Exchanger能够用于遗传算法,遗传算法里需求选出两个人作为交配目标,这时分会交流两人的数据,并运用穿插规矩得出2个交配成果。

2、Exchanger也能够用于校正作业。比方咱们需求将纸制银流经过人工的办法录入成电子银行流水,为了防止过错,选用AB岗两人进行录入,录入到Excel之后,体系需求加载这两个Excel,并对这两个Excel数据进行校正,看看是否录入的共同。代码如下:

 public static void m美智广子ain(String[] args) {
Exchanger exchanger = new Exchanger<>();
new Thread(new Runnable() {
@Override
public void run() {
try {
String a = "银行流水A";
exchanger.exchange(a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
@Override
public void run() {
try {
String b = "银行流水B";
String a = exchanger.exchange(b);
System.out.println("在B中获取到录好喜爱你,Java中的5个并发东西类,你真的了解清楚了吗?,甘草的成效与效果入的A是:"傻馒碎碎念+a);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}

运转成果:

在B中获取到录入的A是:银行流水A

假如两个线程有一个没有抵达exchange办法,则会一向等候,假如忧虑有特殊情况发作,防止一向等候,能够运用exchange(V data, long time, TimeUnit unit)设置最大等候时长。


精彩内容:

Java程序员:这9本高性价比的Java编程书本,你要收好了!

超酷的微信通明头像怎么做?程序员教你一行代码就搞定!

想学习Java的小伙伴留意啦!我整理了一套从根底的Java入门级学习到Java结构内容,送给每一位想要学习Java的小伙伴,想要获取材料,【点击头像,右上角私信:学习】这儿是小白聚集地,欢迎初学和进阶中的小伙伴~