同步工具类之——Latch

来源:互联网 发布:下载锐图网的软件 编辑:程序博客网 时间:2024/06/13 00:19

同步工具类除了最熟悉的阻塞队列之外,还包括Semaphore、Barrier以及Latch。同样,我们也可以创建属于自己的同步工具类。所有的同步工具类都包含了一些特定的结构属性:比如,封装了一些状态,而这些状态将决定执行同步工具类的线程是继续执行海蛇等待,除此而外,还提供了一些方法对状态进行操作,以及高效的等待同步工具类进入到预期的状态。
闭锁最形象的比喻是一扇Gate,在闭锁到达结束状态之前,这扇门始终处于关闭的状态,任何线程都无法通过。而当闭锁到达结束状态,这扇门将打开,进而允许所有的线程通过。一旦闭锁达到结束状态,这扇门将保持打开的状态,不会再关闭。换句话说,闭锁的作用是保持某些活动直到其他活动都完成才继续执行。
举个例子,我们都知道并发在某些情况下,可以极大地提升工作效率,缩短程序的运行时间,那么我们该如何去获取并发程序准确的运行时间,即在所有线程全部就绪的时刻启动时间,而在所有线程全部结束的时刻终止时间。Latch可以做到,看下面程序。

public class TestHarness {    public static String timeTasks(int nThreads,final Runnable[] tasks) throws InterruptedException{        final CountDownLatch startGate=new CountDownLatch(1);        final CountDownLatch endGate=new CountDownLatch(nThreads);        for(Runnable task:tasks){            Thread t=new Thread(){                public void run(){                    try{                        startGate.await();                        try{                            task.run();                        }finally{                            //每个线程最终最后执行将endGate减1                            endGate.countDown();                        }                    }catch(InterruptedException e){                    }                }            };            t.start();        }        long startTime=System.nanoTime();        startGate.countDown();        endGate.await();        long endTime=System.nanoTime();        return "Time: "+(endTime-startTime)+"ns";    }

由于startGate被设置为等待

startGate.await();

因此每个线程首先要做的工作就是在启动门上等待,知道所有的线程全部就绪。并且,我们在为每个线程装载任务时

finally{endGate.countDown();}

保证没个线程最终都会执行使得endGate减1的任务

startGate.countDown();

注意startGate的初值为1,因此调用countDown方法后,门打开,此时线程开始执行

endGate.await();

endGate此时关闭,要做的工作就是等待且为零的时刻,然后打开


如果没用使用Latch工具而去获取并行线程的运行时间,线程在被创建之后将立即执行,显然,先启动的线程势必会领先于后启动的线程,并且活跃线程的数量会随着时间的推移而慢慢减少或者增加,竞争程度也将发生变化。有了这个工具,我们今后在编写并发程序是,只需要调用timeTasks函数,并向其传递任务参数,就可以获取并发时间了。

0 0
原创粉丝点击