并发包下一些并发类

并发包下一些并发类

    引言:JDK1.5的并发包不仅仅提供了前文所说的线程池框架,还提供了一系列并发类,来便于我们编写高并发代码,本文我们来一一介绍。

    一、CountDownLatch类

    代码如下:

package com.example.first;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class UseCountDown {
    public static void main(String args[]) throws InterruptedException {
        CountDownLatch countDownLatch = new CountDownLatch(2);
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程1来了,await阻塞");
                try {
                    countDownLatch.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("阻塞结束,开始执行");
            }
        };
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程2来了");
                countDownLatch.countDown();
            }
        };
        Runnable runnable3 = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程3来了");
                countDownLatch.countDown();
            }
        };
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
        fixedThreadPool.execute(runnable1);
        fixedThreadPool.execute(runnable2);
        fixedThreadPool.execute(runnable3);
        fixedThreadPool.shutdown();
    }
}

    功能主要是提供了两个方法,一个是await(),用于阻塞当前线程,一个是countDown方法,用于改变CountDownLatch对象的状态。

    在CountDownLatch对象初始化的时候,需要在构造函数下加上一个整形的变量i,而await方法就会阻塞线程,只有当其他线程,执行了i次countDown方法,才能将被await阻塞的方法给重新激活。

    使用方式是十分的简单,使用场景主要在监听其他线程的初始化操作,当初始化完毕之后,便会提醒主线程开始运行。

    二、CyclicBarrier类

    代码如下:

package com.example.first;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class UseBarrier {
    public static void main(String args[]) throws InterruptedException {
 //       CountDownLatch countDownLatch = new CountDownLatch(2);
        CyclicBarrier cyclicBarrier = new CyclicBarrier(4);
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程1准备好了");
                try {
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("阻塞结束,线程1开始执行");
            }
        };
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程2准备好了");
                try {
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("阻塞结束,线程2开始执行");
            }
        };
        Runnable runnable3 = new Runnable() {
            @Override
            public void run() {
                System.out.println("线程3准备好了");
                try {
                    cyclicBarrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                System.out.println("阻塞结束,线程3开始执行");
            }
        };
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
        fixedThreadPool.execute(runnable1);
        fixedThreadPool.execute(runnable2);
        fixedThreadPool.execute(runnable3);
        fixedThreadPool.shutdown();
    }
}

    特地去查了一下Barrier是什么意思,大概意思就是栅栏的意思,十分形象。实例化的方式和CountDown很像,都是有一个整数为参数的构造函数,也提供了await方法用于阻塞当前线程,激活线程的时机是当await的数量到达了构造参数中整数的值时。

    十分贴切他的意思--栅栏,只有当线程都到齐了,才能各就各位起跑。

    三、Future和FutureTask类

    代码如下:

package com.example;

import java.util.concurrent.*;

public class UseFuture {
    public static void main(String args[]) throws Exception {
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                Thread.sleep(3000);
                return "future开始!";
            }
        };
        FutureTask<String> futureTask = new FutureTask<String>(callable);
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(5);
        fixedThreadPool.submit(futureTask);
        System.out.println(futureTask.get());
        fixedThreadPool.shutdown();
    }
}

    实现方式,在很早之前写过,但是忘了大概。核心就是要使用Callable接口,重写里面的call方法,call方法有返回值,返回类型为Callable的泛型对象,将Callable出来的对象传入FutureTask的构造方法,再将FutureTask对象传给线程池的submit方法。

    submit和execute在大多数情况下无异,但是submit能够传入callable参数,返回Future参数,值得一说的是,FutureTask实现了Callable接口和Future。最后,当主线程调用了FutureTask的get()方法,便会等待FutureTask任务线程执行,返回call方法的值。这是JDK对Future模式的一种实现。

猜你喜欢

转载自blog.csdn.net/that_is_cool/article/details/80157307