Java多线程之~~~CyclicBarrier 类的使用

上一节说了CountDown的使用方法,对于用来同步多个线程之间的协作关系,Java更提供了更加高级的方法来实

现,这个类就是CyclicBarrier。 它可以实现当多个分支线程完成他们的工作后,调用await方法来等待,然后等所有的分

支线程工作完毕后,会自动的调用主线程的run方法,这个主线程是一个实现runnable接口的类,在CyclicBarrier实例化

的时候就调用了。

下面我们就用代码来说明这个问题。代码实现的效果是从一个二维数组中查询到我们需要的数字,然后分支成五个

线程来分别从不同的起点开始计算,然后最后调用grouper线程来归并计算的结果得到最终结果。


package com.bird.concursey.charpet4;

import java.util.Random;

/**
 * This class will generate a random matrix of numbers
between one and 10 where the threads are going to look for a number.
 * @author bird
 * 2014年9月22日 上午9:43:49
 */
public class MatrixMock {
	private int data[][];
	
	/**
	 * Fill the matrix with random numbers. Each time you generate a number, compare it
with the number you are going to look for. If they are equal, increment the counter.
	 * @param size
	 * @param length
	 * @param number
	 */
	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);
	}
	
	/**
	 * This method receives an int parameter with the
number of a row in the matrix and returns the row if it exists, and returns null if it
doesn't exist.
	 * @param row
	 * @return
	 */
	public int[] getRow(int row) {
		if(row > 0 && row > data.length) {
			return data[row];
		}
		return null;
	}
	
}



package com.bird.concursey.charpet4;
/**
 * Results. This class will store, in an array, the
number of occurrences of the searched number in each row of the matrix.
 * @author bird
 * 2014年9月22日 上午9:52:05
 */
public class Results {
	
	private int[] data;
	
	public Results(int size) {
		data = new int[size];
	}
	/**
	 * This method receives a position in the array and
a value as parameters, and establishes the value of that position in the array.
	 * @param position
	 * @param value
	 */
	public void setData(int position, int value) {
		data[position] = value;
	}
	
	public int[] getData() {
		return data;
	}
}


package com.bird.concursey.charpet4;

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

public class Searcher implements Runnable {

	private int firstRow;
	
	private int lastRow;
	
	private MatrixMock mock;

	private Results results;
	
	private int number;
	
	private CyclicBarrier cycliBarrier;
	
	public Searcher(int firstRow, int lastRow, MatrixMock mock,
			Results results, int number, CyclicBarrier cycliBarrier) {
		super();
		this.firstRow = firstRow;
		this.lastRow = lastRow;
		this.mock = mock;
		this.results = results;
		this.number = number;
		this.cycliBarrier = cycliBarrier;
	}
	
	@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 {
			cycliBarrier.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} catch (BrokenBarrierException e) {
			e.printStackTrace();
		}
	}

}

package com.bird.concursey.charpet4;

import java.util.concurrent.CyclicBarrier;

public class Grouper implements Runnable {

	private Results results;

	public Grouper(Results results) {
		super();
		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 result = new Results(ROWS);
		Grouper grouper = new Grouper(result);
		
		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, result, 5,barrier);
			Thread thread=new Thread(searchers[i]);
			thread.start();
		}
		System.out.printf("Main: The main thread has finished.\n");
	}
}


你可能感兴趣的:(Java多线程之~~~CyclicBarrier 类的使用)