首页 > 技术文章 > 辅助同步器

deliver 2016-07-19 16:01 原文

  java除了提供锁之外,还提供了一些辅助的同步器。

一、CountDownLatch

  作用:常常要有一个线程(master)做汇总,等n个子步骤(线程slave)完成后才能继续操作。用join写只能等子线程完成,而且写起来麻烦;用wait来写也不是那么容易。 

import java.util.concurrent.CountDownLatch;

public class TestThread extends Thread{
    private static final int N=5;
    
    //指定需要完成的countDown次数
    private static CountDownLatch count=new CountDownLatch(N);
    
    public static void main(String[] args) throws InterruptedException{
        TestThread ts[]=new TestThread[5];
        for(int i=0;i<N;i++){
            ts[i]= new TestThread(i);
            ts[i].start();
        }
        //等待N次countDown
        count.await();
        int total=0;
        for(int i=0;i<N;i++) total+=ts[i].getOut();
        System.out.print(total);
            
    }
    
    private int in;
    
    private int out;
    
    public TestThread(int in){
        this.in=in;
    }
    
    public void run(){        
        try {
            out=in*in;
            Thread.sleep(1000);
            //完成子任务,汇报
            count.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }        
    }
    
    public int getOut(){
        return out;
    }
}

 

二、CyclicBarrier

  作用:最直接的作用是n个线程都完成某步操作后才继续。

  CountDownLatch是一个人等N个人,就像老师收试卷,大家交卷就跑了,老师要等齐所有试卷后才能走;

  CyclicBarrier就是N个人互等,就像去春游,要等到最后一个人到了,大家才能出发。

  然而这只是最直接的功能,CyclicBarrier完全可以取代CountDownLatch,而且功能更灵活(可以重置计数)。你可以把它看成一个计数器,能想到的一些操作:

  N个一组地处理一件事。

  语法参考:http://www.cnblogs.com/skywang12345/p/3533995.html

 

三、Semaphore(信号量)

  作用:限制同时访问特定资源的数量,比如同时让5个线程同时上传文件。

public class TestThread {
    
    public static void main(String[] args) throws InterruptedException{
        final int THREAD_COUNT =10;
        for(int i =0 ;i < THREAD_COUNT;i++){
            Thread t= new Thread(new Task1());
            t.start();
        }
    }
    
}

class Task1 implements Runnable{
    //用信号量设置最多5个线程同时访问资源
    private static Semaphore s =new Semaphore(5);
    
    public void run() {
        try {
            s.acquire();
            System.out.println("upload file");
            Thread.sleep(1000);
            s.release();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }    
}

 

四、Exchanger

  作用:主要用于线程间交换数据

推荐阅读