动力节点旗下在线教育品牌  |  咨询热线:400-8080-105 学Java全栈,上蛙课网
首页 > 文章

多线程的得力助手—java辅助类工具

06-22 19:24 283浏览
举报 T字号
  • 大字
  • 中字
  • 小字

java多线程编程中为了帮助大家更好地进行并发编程java辅助类工具是必不可少的。为此,java向我们提供了一些非常有用的辅助类,比如CountDownLatch,CyclicBarrier、Semaphore和exchanger。接下来,我们逐个了解这些java多线程编程的得力助手java辅助类工具。

一、CountDownLatch

它是一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。 其机制是:当多个(具体数量等于初始化CountDownLatch时的count参数的值)线程都达到了预期状态或完成预期工作时触发事件,其他线程可以等待这个事件来触发自己的后续工作。这里需要注意的是,等待的线程可以是多个,即CountDownLatch是可以唤醒多个等待的线程的。达到自己预期状态的线程会调用CountDownLatch的countDown方法,而等待的线程会调用CountDownLatch的await方法。

CountDownLatch 很适合用来将一个任务分为n个独立的部分,等这些部分都完成后继续接下来的任务,CountDownLatch 只能出发一次,计数值不能被重置。

代码实现:

public class Testcutdownlatch {

    public static void main(String[] args) {

        final CountDownLatch latch = new CountDownLatch(3);

 

 

        new Thread(new Runnable() {

            public void run() {

                try {

                    latch.await();

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

 

                System.out.println("Waiter Released");

            }

        }).start();

        new Thread(new Runnable() {

            public void run() {

                try {

                    Thread.sleep(1000);

                    latch.countDown();

                    Thread.sleep(1000);

                    latch.countDown();

                    Thread.sleep(1000);

                    latch.countDown();

 

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

 

            }

        }).start();

 

    }

 

}

输出结果:

Waiter Released

cyclicbarrier

可以协同多个线程,让多个线程在这个屏障前等待,直到所有线程都达到了这个屏障时,再一起继续执行后面的动作。

CyclicBarrier适用于多个线程有固定的多步需要执行,线程间互相等待,当都执行完了,再一起执行下一步。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier

代码实现:

public class Testcyclicbarrier {

    public static void main(String[] args) {

        final CyclicBarrier barrier1 = new CyclicBarrier(2, new Runnable() {

            public void run() {

                System.out.println("BarrierAction 1 executed ");

            }

        });

        final CyclicBarrier barrier2 = new CyclicBarrier(2, new Runnable() {

            public void run() {

                System.out.println("BarrierAction 2 executed ");

            }

        });

        for (int i=0;i<3;i++)

        {

            new Thread(new Runnable() {

                public void run() {

                    try {

                        Thread.sleep(1000);

                        System.out.println(Thread.currentThread().getName()+"waited barrier1");

                        barrier1.await();

                        Thread.sleep(1000);

                        System.out.println(Thread.currentThread().getName()+"waited barrier2");

                        barrier2.await();

 

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }catch (BrokenBarrierException e) {

                        e.printStackTrace();

                    }

                }

            }).start();

        }

    }

}

输出结果:

Thread-0waited barrier1

Thread-2waited barrier1

Thread-1waited barrier1

BarrierAction 1 executed

Thread-0waited barrier2

Thread-1waited barrier2

BarrierAction 2 executed

三、Exchanger

Exchanger 类方便了两个共同操作线程之间的双向交换;这样,就像具有计数为 2 的 CyclicBarrier,并且两个线程在都到达屏障时可以“交换”一些状态。(Exchanger 模式有时也称为聚集。)

Exchanger 通常用于一个线程填充缓冲(通过读取 socket),而另一个线程清空缓冲(通过处理从 socket 收到的命令)的情况。当两个线程在屏障处集合时,它们交换缓冲。

代码实现:

public class Testexchanger {

    public static void main(String[]args){

        final Exchanger exchanger = new Exchanger();

        //Action action=new Action();

        new Thread(new Runnable() {

            public void run() {

                try {

                    Thread.sleep(1000);

                    exchanger.exchange(Thread.currentThread().getName()+"data");

                    System.out.println(Thread.currentThread().getName()+"我交给你了");

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }).start();

        new Thread(new Runnable() {

            public void run() {

                try {

                    exchanger.exchange(Thread.currentThread().getName()+"data");

                    System.out.println(Thread.currentThread().getName()+"我交给你了");

 

                } catch (InterruptedException e) {

                    e.printStackTrace();

                }

            }

        }).start();

 

    }

 

}

输出结果:

Thread-0我交给你了

Thread-1我交给你了

四、Semaphore

Semaphore 信号量对象管理的信号就像令牌,构造时传入个数,总数就是控制并发的数量。我们需要控制并发的代码,执行前先获取信号(通过acquire获取信号许可),执行后归还信号(通过release归还信号许可)。每次acquire成功返回后,Semaphore可用的信号量就会减少一个,如果没有可用的信号,acquire调用就会阻塞,等待有release调用释放信号后,acquire才会得到信号并返回。

如果Semaphore管理的信号量为1个,那么就退化到互斥锁了;如果多于一个信号量,则主要用于控制并发数。与通过控制线程数来控制并发数的方式相比,通过Semaphore来控制并发数可以控制得更加细粒度,因为真正被控制最大并发的代码放到acquire和release之间就行了。

代码实现:

public class Testsemophore {

    public static void main(String[]args){

        final Semaphore semaphore = new Semaphore(3);

 

        for (int i=0;i<7;i++)

        {

            new Thread(new Runnable() {

                public void run() {

                    try {

                        semaphore.acquire();

                        System.out.println(Thread.currentThread().getName()+"获取到许可");

                        Thread.sleep(1000);

                        semaphore.release();

 

                    } catch (InterruptedException e) {

                        e.printStackTrace();

                    }

                }

            }).start();

        }

    }

}

输出结果:

Thread-0获取到许可

Thread-2获取到许可

Thread-1获取到许可

Thread-3获取到许可

Thread-4获取到许可

Thread-5获取到许可

Thread-6获取到许可

   其实这些java辅助类工具何尝不像是那些无私奉献的人们呢。成就了别人,默默做着自己。“春蚕到死丝方尽,蜡炬成灰泪始干。”相信我们在java多线程工具类的帮助下,能够如鱼得水,使java多线程编程变得更加规范合理,使得我们能够不断创造新的编程世界里的奇迹。

1人推荐
共同学习,写下你的评论
0条评论
冷酷自尊VIP
程序员冷酷自尊VIP

5篇文章贡献26210字

作者相关文章更多>

推荐相关文章更多>

Java数据结构

HelloWorld10-31 08:24

浅谈MySQL中SQL优化的常用方法

军哥08-12 23:29

五分钟读懂UML类图

江湖人称小李白12-10 10:41

MyBatis开发框架的四大核心

IT逐梦者08-17 21:43

一次搞定continue,break和return

HelloWorld11-06 11:19

发评论

举报

0/150

取消