并发闭锁之CountDownLatch和FutureTask

原文链接: http://www.cnblogs.com/dolphin0520/p/3949310.html

闭锁:一种同步工具类,可以用来确保某些活动指导其他活动都完成后才执行。
CountDownLatch:一种闭锁的实现,可以使一个或多个线程等待一组事件发生。

    public void CountDownLatch(int count) {...}

CountDownLatch的构造器中的count即线程数(正数),相当于一个递减计数器的作用,count只能初始化时设置一次,之后便不能更改。每个线程完成之后,便立即调用 CountDownLatch.countDown()方法来通知CountDownLatch对象,count减一。count的值等于0,主线程就能通过await()方法,恢复执行自己的任务。await()方法会一直阻塞,直到count为0或等待中的线程中断或等待超时。

FutureTask:一种闭锁的实现,实现了Future接口。可以用来执行一个高开销的计算,并且计算结果将在稍后使用。通过提前启动计算,减少等待结果的时间。Future.get的行为取决于任务的状态。如果任务已经完成,那么get会立即返回结果,否则get将阻塞直到任务进入完成状态,然后返回结果或者抛出异常。

已下内容原文请参考:http://www.cnblogs.com/dolphin0520/p/3949310.html
Callable、Runnable、Future和FutureTask的关系:
并发闭锁之CountDownLatch和FutureTask_第1张图片
java.lang.Runnable是一个接口,在它里面只声明了一个run()方法,且执行完任务之后无法返回任何结果:

public interface Runnable {
    public abstract void run();
}

Callable位于java.util.concurrent包下,也是一个接口,在它里面也只声明了一个call()方法,返回的类型就是传递进来的V类型:

public interface Callable {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call() throws Exception;
}

Callable一般配合ExecutorService来使用。
Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。Future类位于java.util.concurrent包下,它是一个接口:

public interface Future {
    boolean cancel(boolean mayInterruptIfRunning);
    boolean isCancelled();
    boolean isDone();
    V get() throws InterruptedException, ExecutionException;
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

在Future接口中声明了5个方法,下面依次解释每个方法的作用:
cancel方法:用来取消任务,如果取消任务成功则返回true,如果取消任务失败则返回false。参数mayInterruptIfRunning表示是否允许取消正在执行却没有执行完毕的任务,如果设置true,则表示可以取消正在执行过程中的任务。如果任务已经完成,则无论mayInterruptIfRunning为true还是false,此方法肯定返回false,即如果取消已经完成的任务会返回false;如果任务正在执行,若mayInterruptIfRunning设置为true,则返回true,若mayInterruptIfRunning设置为false,则返回false;如果任务还没有执行,则无论mayInterruptIfRunning为true还是false,肯定返回true。
isCancelled方法:表示任务是否被取消成功,如果在任务正常完成前被取消成功,则返回 true。
isDone方法:表示任务是否已经完成,若任务完成,则返回true;
get()方法:用来获取执行结果,这个方法会产生阻塞,会一直等到任务执行完毕才返回;
get(long timeout, TimeUnit unit):用来获取执行结果,如果在指定时间内,还没获取到结果,就直接返回null。
Future通过这5个方法提供了三种功能:
  1)判断任务是否完成;
  2)能够中断任务;
  3)能够获取任务执行结果。
FutureTask:因为Future只是一个接口,所以是无法直接用来创建对象使用的,因此就有了FutureTask。
FutureTask类实现了RunnableFuture接口,RunnableFuture继承了Runnable接口和Future接口,。所以FutureTask既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值。

public class FutureTask implements RunnableFuture
public interface RunnableFuture extends Runnable, Future {
    void run();
}

FutureTask提供了2个构造器:

public FutureTask(Callable callable) {
}
public FutureTask(Runnable runnable, V result) {
}

CountDownLatch和FutureTask的区别:CountDownLatch主要是提供一个计数器功能,当所有线程执行完后,在将所有线程一起放行。起到阻塞线程的功能。FutureTask主要对线程的结果进行取消、查询是否完成、获取结果。也可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。即get方法也可以起到阻塞线程的功能。

FutureTask使用Demo:

public class test {

    public static void main(String[] args) throws Exception{
        test();
    }
    public static void test() throws Exception{
        FutureTask futureTask = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                return demo1();
            }
        });
        FutureTask futureTask1 = new FutureTask(new Callable() {
            @Override
            public Object call() throws Exception {
                return demo2();
            }
        });
        for (int i=1; i<3 ;i++) {
            if(i==1) {
                new Thread(futureTask).start();
            }else{
                new Thread(futureTask1).start();
            }
        }
        Student stu1 = futureTask.get();
        System.out.println(stu1);
        System.out.println("线程1执行结束");
        Student stu2 = futureTask1.get();
        System.out.println(stu2);
        System.out.println("线程2执行结束");
        System.out.println("主线程执行结束====");

    }

    private static Student demo1() throws Exception{
        System.out.println("线程1执行======");
        return new Student();
    }
    private static Student demo2() throws Exception{
        System.out.println("线程2开始执行======");
        Thread.sleep(5000);
        System.out.println("线程2执行结束======");
        return new Student();
    }
}
class Student{
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

你可能感兴趣的:(并发编程,java并发编程)