java7高并发4

semaphore

semaphore 有个参数counter 控制资源数量。counter 》0表示有资源可以访问,=0表示没有资源线程阻塞。semaphore.acquire()表示counter -1,semaphore.release()表示counter +1

public class PrintQueue {
    private final Semaphore semaphore;
    public PrintQueue(){
        semaphore=new Semaphore(1);
    }
    public void printJob (Object document) {
        try {
            semaphore.acquire();
            long duration = (long) (Math.random() * 10);
            System.out.printf("%s: PrintQueue: Printing a Job during %d seconds\n", Thread.currentThread().getName(), duration);
            Thread.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    }
    public static void main (String args[]){
        PrintQueue printQueue=new PrintQueue();
        Thread thread[]=new Thread[10];
        for (int i=0; i<10; i++){
            thread[i]=new Thread(new Job(printQueue),"Thread"+i);
        }
        for (int i=0; i<10; i++){
            thread[i].start();
        }
    }
}
class Job implements Runnable {
    private PrintQueue printQueue;
    public Job(PrintQueue printQueue){
        this.printQueue=printQueue;
    }
    @Override
    public void run() {
        System.out.printf("%s: Going to print a job\n",Thread.currentThread().getName());
        printQueue.printJob(new Object());
        System.out.printf("%s: The document has been printed\n",Thread.currentThread().getName());
    }
}

acquireUninterruptibly():忽略中断。正常acquire()方法或睡眠线程,在阻塞期间有可能被中断,此时会跑出InterruptedException 异常
tryAcquire(): 尝试获取资源,又返回true没有资源返回false不会阻塞
semaphores也有公平机制,默认非公平,可以构造器中指定

多个线程同时访问

public class PrintQueue {
    private boolean freePrinters[];
    private Lock lockPrinters;
    private Semaphore semaphore;
    public PrintQueue(){
        semaphore=new Semaphore(3);
        freePrinters=new boolean[3];
        for (int i=0; i<3; i++){
            freePrinters[i]=true;
        }
        lockPrinters=new ReentrantLock();
    }
    public void printJob (Object document){
        try {
            semaphore.acquire();
            int assignedPrinter=getPrinter();
            long duration=(long)(Math.random()*10);
            System.out.printf("%s: PrintQueue: Printing a Job in Printer%d during %d seconds\n",Thread.currentThread().getName(),assignedPrinter,duration);
            TimeUnit.SECONDS.sleep(duration);
            freePrinters[assignedPrinter]=true;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            semaphore.release();
        }
    }
    private int getPrinter() {
        int ret=-1;
        try {
            lockPrinters.lock();
            for (int i=0; i<freePrinters.length; i++) {
                if (freePrinters[i]){
                    ret=i;
                    freePrinters[i]=false;
                    break;
                }
            }    } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lockPrinters.unlock();
        }
        return ret;
    }
}

semaphore 控制三个线程同时运行,每个线程拥有一个print资源用完释放资源。
acquire(), acquireUninterruptibly(), tryAcquire(),release() 方法有个参数控制一次获得多少,例如acquire(int permits) ,不写permits默认是1

CountDownLatch

public class Videoconference implements Runnable {
    private final CountDownLatch controller;
    public Videoconference(int number) {
        controller=new CountDownLatch(number);
    }
    public void arrive(String name){
        System.out.printf("%s has arrived.",name);
        controller.countDown();
        System.out.printf("VideoConference: Waiting for %d participants.\n",controller.getCount());
    }
    @Override
    public void run() {
        System.out.printf("VideoConference: Initialization: %d participants.\n",controller.getCount());
        try {
            controller.await();
            System.out.printf("VideoConference: All the participants have come\n");
            System.out.printf("VideoConference: Let's start...\n");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) {
        Videoconference conference=new Videoconference(10);
        Thread threadConference=new Thread(conference);
        threadConference.start();
        for (int i=0; i<10; i++){
            Participant p=new Participant(conference, "Participant "+i);
            Thread t=new Thread(p);
            t.start();
        }
    }
}
class Participant implements Runnable {
    private Videoconference conference;
    private String name;
    public Participant(Videoconference conference, String name) {
        this.conference=conference;
        this.name=name;
    }
    @Override
    public void run() {
        long duration=(long)(Math.random()*10);
        try {
            TimeUnit.SECONDS.sleep(duration);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        conference.arrive(name);
    }
}

CountDownLatch 有三个基本要素
1.初始化值决定CountDownLatch 类需要等待多少事件
2.await()方法,需要等待所有事件执行完才会执行的线程调用这个方法
3.countDown()方法,被结束的事件线程调用
CountDownLatch 只可以调用countDown()修改count
await(longtime,TimeUnitunit):count到达0或者指定时间到达执行

CyclicBarrier

public class MatrixMock {
    private int data[][];
    public MatrixMock(int size, int length, int number){
        int counter=0;
        data=new int[size][length];
        Random random=new Random();
        for (int i=0; i<size; i++) {
            for (int j=0; j<length; j++){
                data[i][j]=random.nextInt(10);
                if (data[i][j]==number){
                    counter++;
                }
            }
        }
        System.out.printf("Mock: There are %d ocurrences of number in generated data.\n",counter,number);
    }
    public int[] getRow(int row){
        if ((row>=0)&&(row<data.length)){
            return data[row];
        }
        return null;
    }
}
class Results {
    private int data[];
    public Results(int size){
        data=new int[size];
    }
    public void  setData(int position, int value){
        data[position]=value;
    }
    public int[] getData(){
        return data;
    }
}
class Searcher implements Runnable {
    private int firstRow;

    private int lastRow;
    private MatrixMock mock;
    private Results results;
    private int number;
    private final CyclicBarrier barrier;
    public Searcher(int firstRow, int lastRow, MatrixMock mock, Results results, int number, CyclicBarrier barrier){
        this.firstRow=firstRow;
        this.lastRow=lastRow;
        this.mock=mock;
        this.results=results;
        this.number=number;
        this.barrier=barrier;
    }
    @Override
    public void run() {
        int counter;
        System.out.printf("%s: Processing lines from %d to %d.\n", Thread.currentThread().getName(), firstRow, lastRow);
        for (int i = firstRow; i < lastRow; i++) {
            int row[] = mock.getRow(i);
            counter = 0;
            for (int j = 0; j < row.length; j++) {
                if (row[j] == number) {
                    counter++;
                }
            }
            results.setData(i, counter);
        }
        System.out.printf("%s: Lines processed.\n", Thread.currentThread().getName());
        try {
            barrier.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (BrokenBarrierException e) {
            e.printStackTrace();
        }
    }
}
class Grouper implements Runnable {
    private Results results;
    public Grouper(Results results){
        this.results=results;
    }
    @Override
    public void run() {
        int finalResult=0;
        System.out.printf("Grouper: Processing results...\n");
        int data[]=results.getData();
        for (int number:data){
            finalResult+=number;
        }
        System.out.printf("Grouper: Total result: %d.\n",finalResult);
    }
    public static void main(String[] args) {
        final int ROWS=10000;
        final int NUMBERS=1000;
        final int SEARCH=5;
        final int PARTICIPANTS=5;
        final int LINES_PARTICIPANT=2000;
        MatrixMock mock=new MatrixMock(ROWS, NUMBERS,SEARCH);
        Results results=new Results(ROWS);
        Grouper grouper=new Grouper(results);
        CyclicBarrier barrier=new CyclicBarrier(PARTICIPANTS,grouper);
        Searcher searchers[]=new Searcher[PARTICIPANTS];
        for (int i=0; i<PARTICIPANTS; i++){
            searchers[i]=new Searcher(i*LINES_PARTICIPANT, (i*LINES_PARTICIPANT)+LINES_PARTICIPANT, mock, results, 5,barrier);
            Thread thread=new Thread(searchers[i]);
            thread.start();
        }
        System.out.printf("Main: The main thread has finished.\n");
    }
}
5个thread都执行完后,grouper线程会执行

CyclicBarrier 类初始化的时候 构造器有个int参数,指示多少个线程需要同步。当一个线程执行到某个点需要等待其他线程执行就调用await() 方法,此时该线程睡眠,直到其他线程到达。所有线程都到达await() 方法之后,这些线程才会继续执行
await(longtime,TimeUnitunit): 线程会睡眠直到被中断、时间到达或者CyclicBarrier到达
getNumberWaiting():等待中的线程数量
getParties():将要同步的线程数量
reset():重置到初始状态,等待中的线程会收到BrokenBarrierException 异常

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值