Zookeeper學習筆記(六)分佈式Barrier

當我們需要多個線程同時啓動時,我們可以使用jdk自帶的CycliBarrier。先來看看它的常用用法:

package com.my.CuratorTest;

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

/**
 * Title: <br/>
 * Intention: <br/>
 * <p>
 * Class Name: com.my.CuratorTest.CycliBarrierTest<br/>
 * Create Date: 2017/8/26 11:18 <br/>
 * Project Name: MyTest <br/>
 * Company:  All Rights Reserved. <br/>
 * Copyright © 2017 <br/>
 * </p>
 * <p>
 * author: GaoWei <br/>
 * 1st_examiner: <br/>
 * 2nd_examiner: <br/>
 * </p>
 *
 * @version 1.0
 * @since JDK 1.7
 */
public class CycliBarrierTest {

	public static void main(String[] args) {
		CyclicBarrier barrier = new CyclicBarrier(5);
		for (int i = 0; i < 5; i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					System.out.println(Thread.currentThread().getName()+", 等待...");
					try {
						barrier.await();
						System.out.println(Thread.currentThread().getName()+ ", " + System.currentTimeMillis() + ", 開始工作");
					} catch (InterruptedException e) {
						e.printStackTrace();
					} catch (BrokenBarrierException e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
	}
}

運行結果:

Thread-3, 等待...
Thread-1, 等待...
Thread-0, 等待...
Thread-2, 等待...
Thread-4, 等待...
Thread-4, 1503736464892, 開始工作
Thread-3, 1503736464892, 開始工作
Thread-0, 1503736464892, 開始工作
Thread-1, 1503736464892, 開始工作
Thread-2, 1503736464892, 開始工作

那麼,在分佈式環境下如何解決多個線程同時啓動的問題呢?Curator爲我們提供了DistributedBarrier(主線程觸發barrier釋放) 和 DistributedDoubleBarrier(線程自發觸發barrier釋放)。

DistributedBarrier的使用如下,拷貝書上代碼:

package com.my.CuratorTest;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.barriers.DistributedBarrier;
import org.apache.curator.retry.ExponentialBackoffRetry;

/**
 * Title: <br/>
 * Intention: <br/>
 * <p>
 * Class Name: com.my.CuratorTest.RecipesBarrier<br/>
 * Create Date: 2017/8/26 11:07 <br/>
 * Project Name: MyTest <br/>
 * Company:  All Rights Reserved. <br/>
 * Copyright © 2017 <br/>
 * </p>
 * <p>
 * author: GaoWei <br/>
 * 1st_examiner: <br/>
 * 2nd_examiner: <br/>
 * </p>
 *
 * @version 1.0
 * @since JDK 1.7
 */
public class RecipesBarrier {

	static String barrierPath = "/curator_recipes_barrier_path";
	static DistributedBarrier barrier;

	public static void main(String[] args) throws Exception {
		for(int i=0;i<5;i++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					CuratorFramework client = CuratorFrameworkFactory.builder()
							.connectString("127.0.0.1:2181")
							.retryPolicy(new ExponentialBackoffRetry(1000, 8))
							.build();
					client.start();
					barrier = new DistributedBarrier(client, barrierPath);
					System.out.println(Thread.currentThread().getName() + "號barrier設置");
					try {
						barrier.setBarrier();
						barrier.waitOnBarrier();
						System.err.println(Thread.currentThread().getName() + " 啓動...");
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
		Thread.sleep(2000);
		barrier.removeBarrier();
	}
}

運行結果:

Thread-4號barrier設置
Thread-2號barrier設置
Thread-3號barrier設置
Thread-0號barrier設置
Thread-1號barrier設置
Thread-3 啓動...
Thread-4 啓動...
Thread-2 啓動...
Thread-0 啓動...
Thread-1 啓動...

DistributedDoubleBarrier的使用如下:

package com.my.CuratorTest;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.barriers.DistributedDoubleBarrier;
import org.apache.curator.retry.ExponentialBackoffRetry;

/**
 * Title: <br/>
 * Intention: <br/>
 * <p>
 * Class Name: com.my.CuratorTest.RecipesBarrier2<br/>
 * Create Date: 2017/8/26 16:05 <br/>
 * Project Name: MyTest <br/>
 * Company:  All Rights Reserved. <br/>
 * Copyright © 2017 <br/>
 * </p>
 * <p>
 * author: GaoWei <br/>
 * 1st_examiner: <br/>
 * 2nd_examiner: <br/>
 * </p>
 *
 * @version 1.0
 * @since JDK 1.7
 */
public class RecipesBarrier2 {

	static String barrierPath = "/curator_recipes_barrier_path";

	public static void main(String[] args) {
		for (int i = 0; i < 5; i ++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						CuratorFramework client = CuratorFrameworkFactory.builder()
								.connectString("127.0.0.1:2181")
								.retryPolicy(new ExponentialBackoffRetry(1000, 3))
								.build();
						client.start();
						DistributedDoubleBarrier barrier = new DistributedDoubleBarrier(client, barrierPath, 5);
						Thread.sleep(Math.round(Math.random() * 3000));
						System.out.println(Thread.currentThread().getName() +" 號進入barrier");
						barrier.enter();
						System.out.println(Thread.currentThread().getName() +" 啓動...");
						Thread.sleep(Math.round(Math.random() * 3000));
						barrier.leave();
						System.out.println(Thread.currentThread().getName() +" 退出...");
					} catch (InterruptedException e) {
						e.printStackTrace();
					} catch (Exception e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
	}
}

運行結果:

Thread-2 號進入barrier
Thread-1 號進入barrier
Thread-4 號進入barrier
Thread-0 號進入barrier
Thread-3 號進入barrier
Thread-3 啓動...
Thread-4 啓動...
Thread-1 啓動...
Thread-0 啓動...
Thread-2 啓動...
Thread-2 退出...
Thread-4 退出...
Thread-0 退出...
Thread-1 退出...
Thread-3 退出...
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章