java中的线程协调与线程间的数据交换

Java中提供多种方式协调线程的工作。

CountDownLatch:当多个也就是具体的数量等于CountDownLatch初始化参数的时候。线程达到了预期状态或者完成了预期工作时触发事件,其他线程可以等待这个事件来触发自己的后续工作。等待的线程是多个。达到了预期状态的线程会调用CountDownLatch的countDown方法。等待的线程会调用CountDownLatch的await方法。

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CountDownLatchDemo {

	static ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(5) );
	
	public static void main(String[] args) throws InterruptedException {
		int count = 10;
		final CountDownLatch latch = new CountDownLatch(count);
		int[] datas = new int[10240];
		int step = datas.length / count;
		for (int i=0; i<count; i++) {
			int start = i * step;
			int end = (i+1) * step;
			if (i == count -1) 
				end = datas.length;
			
			tp.execute(new MyRunable(latch, datas, start, end));
		}
		
		latch.await();
	}
}

import java.util.concurrent.CountDownLatch;

public class MyRunable implements Runnable {
	CountDownLatch latch;
	int[] datas;
	 int start;
	 int end;
	 

	public CountDownLatch getLatch() {
		return latch;
	}

	public void setLatch(CountDownLatch latch) {
		this.latch = latch;
	}

	public int[] getDatas() {
		return datas;
	}

	public void setDatas(int[] datas) {
		this.datas = datas;
	}

	public int getStart() {
		return start;
	}

	public void setStart(int start) {
		this.start = start;
	}

	public int getEnd() {
		return end;
	}

	public void setEnd(int end) {
		this.end = end;
	}

	public MyRunable(CountDownLatch latch, int[] datas, int start, int end) {
		this.latch = latch;
		this.datas = datas;
		this.start = start;
		this.end = end;
	}

	@Override
	public void run() {
		latch.countDown();
	}

}


CyclicBarrier是指循环屏障。它可以协同多个线程,让多个线程在这个屏障前等待。直到所有的线程都达到了这个屏障,再一起继续执行后面的工作。

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class CyclicBarrierDemo {

	static ThreadPoolExecutor tp = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(5) );
	
	public static void main(String[] args) throws InterruptedException {
		int count = 10;
		final CyclicBarrier latch = new CyclicBarrier(count);
		int[] datas = new int[10240];
		int step = datas.length / count;
		for (int i=0; i<count; i++) {
			int start = i * step;
			int end = (i+1) * step;
			if (i == count -1) 
				end = datas.length;
			
			tp.execute(new MyRunable1(latch, datas, start, end));
		}
		
		try {
			latch.await();
		} catch (BrokenBarrierException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

CyclicBarrier与CountDownLatch都用于线程之间的协调。两者之间的差别在于,CountDownLatch是在多个线程都进行了latch.countDown方法后,才会触发事件,唤醒await在latch上的线程。而执行countDown的线程,行完countDown后会继续自己的线程工作。CyclicBarrier用于同步所有调用await方法的线程,并且等待所有线程都到await方法时,这些线程才继续各自的工作。


Exchanger

不同线程之间的数据交换用Exchanger。当一个线程的方法执行调用exchanger.exchange的时候,会等待其他线程也执行到调用这个方法。然后交换彼此之间的数据

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Exchanger;

public class ExchangerDemo {

	public static void main(String[] args) {
		final Exchanger<List<Integer>> exchanger = new Exchanger<List<Integer>>();
		new Thread(){
			public void run(){
				List<Integer> list = new ArrayList<Integer>(2);
				list.add(1);
				list.add(2);
				
				try {
					list = exchanger.exchange(list);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("thread1:" + list);
			}
		}.start();
		
		new Thread(){
			public void run(){
				List<Integer> list = new ArrayList<Integer>(3);
				list.add(3);
				list.add(4);
				list.add(5);
				try {
					list = exchanger.exchange(list);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println("thread2:" + list);
			}
		}.start();
		
	}
}



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。