1. 程式人生 > >模仿CyclicBarrier,自定義自己屏障類

模仿CyclicBarrier,自定義自己屏障類

on() exc urn oid lee rand () pri rup

簡介

在這裏模仿CyclicBarrier,自定義一個自己多線程屏障類,裏面有個計時器count,count為0時,才喚醒線程,否則就await掛起,(沒錯就是用的object類的掛起和喚醒全部線程方法)

1、MyCyclicBarrier

package com.jacky;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by jacky on 2018/2/11.
 
*/ public class MyCyclicBarrier { private int count; private int parties; private Runnable barrierAction; private final ReentrantLock lock = new ReentrantLock(); private final Condition condition = lock.newCondition(); public MyCyclicBarrier(int parties,Runnable barrierAction){
if (parties <=0){ throw new IllegalArgumentException(); } this.parties = parties; this.count = parties; this.barrierAction = barrierAction; } public int await() throws InterruptedException,BrokenBarrierException { lock.lock(); try
{ int index = --count; if (index ==0){ if (null == barrierAction){ barrierAction.run(); } condition.signalAll(); return index; } for (;;){ condition.await(); return index; } }finally { lock.unlock(); } } }

2、測試

package com.jacky;

import com.sun.org.apache.xpath.internal.SourceTree;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;

/**
 * Created by jacky on 2018/2/11.
 */
public class CyclicBarrierDemo {
    public static void main(String[] args) throws InterruptedException {
        MyCyclicBarrier barrier = new MyCyclicBarrier(3, new Runnable() {
            @Override
            public void run() {
                Thread thread = Thread.currentThread();
                System.out.println("barrierAction start"+thread.getName());
                try {
                    Thread.sleep((int)Math.random()*300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("barrierAction start"+thread.getName());
            }
        });
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep((int)(Math.random()*100));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Thread thread = Thread.currentThread();
                System.out.println("thread start:"+thread.getName());
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println("thread end:"+thread.getName());
            }
        };
        Runnable runnable2 = new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep((int)(Math.random()*200));
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Thread thread = Thread.currentThread();
                System.out.println("thread start:"+thread.getName());
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                try {
                    barrier.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (BrokenBarrierException e) {
                    e.printStackTrace();
                }
                System.out.println("thread end:"+thread.getName());
            }
        };
        Thread thread1 = new Thread(runnable1);
        Thread thread2 = new Thread(runnable2);
        Thread thread3 = new Thread(runnable1);
        thread1.start();
        thread2.start();
        thread3.start();
        Thread.sleep(2000);
        System.out.println("thread1:"+thread1.getName()+","+thread1.getState());
        System.out.println("thread2:"+thread2.getName()+","+thread2.getState());
        System.out.println("thread3:"+thread3.getName()+","+thread3.getState());
    }
}

模仿CyclicBarrier,自定義自己屏障類