`

同步器

阅读更多

Latch 门闩

CountDownLatch 的一个有用特性是,它不要求调用 countDown 方法的线程等到计数到达零时才继续,

而在所有线程都能通过之前,它只是阻止任何线程继续通过一个 await。

计数无法被重置。 如果需要重置计数,请考虑使用 CyclicBarrier。
确保一组特定的活动在某一活动完成前,一直处于等待。比如:
1、在资源R初始化之前,使用该资源的所有活动都处于等待。
2、释放服务S前,完成所有依赖于S的服务。
3、开始多人游戏前,确保所有参与者的终端都连接完毕。

例子

public class TestHarness {

	public long timeTasks(int nThreads, final Runnable task) throws InterruptedException {
		final CountDownLatch startGate = new CountDownLatch(1);
		final CountDownLatch endGate = new CountDownLatch(nThreads);

		for (int i = 0; i < nThreads; i++) {
			Thread t = new Thread() {
				public void run() {
					try {
						startGate.await();
						try {
							task.run();
						} finally {
							endGate.countDown();
						}
					} catch (InterruptedException ignored) {
					}
				}
			};
			t.start();
		}

		long start = System.nanoTime();

		System.out.println("open!");
		startGate.countDown();

		endGate.await();
		System.out.println("close!");

		long end = System.nanoTime();
		return end - start;
	}

	public static void main(String[] ss) throws InterruptedException {
		System.out.println(new TestHarness().timeTasks(10, new Thread() {
			public void run() {
				System.out.println("I am in!");
			}
		}));
	}
}
 

FutureTask 未来的任务

可取消的异步计算。利用开始和取消计算的方法、查询计算是否完成的方法和获取计算结果的方法,此类提供了对Future的基本实现。

仅在计算完成时才能获取结果;如果计算尚未完成,则阻塞 get 方法。一旦计算完成,就不能再重新开始或取消计算。

三态:

waiting to run

running

completed

 

例子1

public class Preloader {
	
	private ProductInfo loadProductInfo() throws DataLoadException {
		System.out.println("load product information from a database...");
		return null;
	}

	private final FutureTask<ProductInfo> future = new FutureTask<ProductInfo>(
			new Callable<ProductInfo>() {
				public ProductInfo call() throws DataLoadException {
					return loadProductInfo();
				}
			});
	private final Thread thread = new Thread(future);

	public void start() {
		thread.start();
		System.out.println("thread is started.");
	}

	public ProductInfo get() throws DataLoadException, InterruptedException {
		try {
			return future.get();
		} catch (ExecutionException e) {
			Throwable cause = e.getCause();
			if (cause instanceof DataLoadException)
				throw (DataLoadException) cause;
			else
				throw LaunderThrowable.launderThrowable(cause);
		}
	}

	interface ProductInfo {
	}
	
	public static void main(String[] ss) throws DataLoadException, InterruptedException{
		Preloader loader=new Preloader();
		loader.start();
		System.out.println("---- ----");
		loader.get();
	}
}

class DataLoadException extends Exception {
	private static final long serialVersionUID = 7984266484349694761L;
}
 

例子2

package creative.fire.concurrent.cache;

import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class ResourceCache {
	private static ConcurrentHashMap<String, FutureTask<Resource>> resourceMap = new ConcurrentHashMap<String, FutureTask<Resource>>(
			1000, 0.7f);

	private Resource retrieveFromDB(String resId) {
		Resource res = null;
		System.out.println("retrieve " + resId + " from database.");
		return res;
	}

	public Resource get(final String resId) throws InterruptedException,
			ExecutionException {
		FutureTask<Resource> resTask = resourceMap.get(resId);
		if (resTask != null){
			System.out.println("get " + resId + " from cache.");
			return resTask.get();
		}
			

		FutureTask<Resource> newTask = new FutureTask<Resource>(
				new Callable<Resource>() {
					public Resource call() throws Exception {
						return retrieveFromDB(resId);
					}
				});

		FutureTask<Resource> task = resourceMap.putIfAbsent(resId, newTask);
		if (task == null) {
			task = newTask;
			task.run();
		}
		return task.get();
	}

	interface Resource {

	}

	public static void main(String[] ss) throws InterruptedException,ExecutionException {
		ResourceCache cache = new ResourceCache();
		cache.get("Device_ABC");
		cache.get("Device_ABC");
	}
}

 

Semaphore 信号
控制一组活动,它们在同一时间访问特定某一资源或者执行某个操作。

如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。

Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目。

例子

public class SemaphoreBoundedBuffer<E> {
	private final Semaphore availableItems, availableSpaces;
	@GuardedBy("this")
	private final E[] items;
	@GuardedBy("this")
	private int putPosition = 0, takePosition = 0;

	public SemaphoreBoundedBuffer(int capacity) {
		if (capacity <= 0)
			throw new IllegalArgumentException();
		availableItems = new Semaphore(0);
		availableSpaces = new Semaphore(capacity);
		items = (E[]) new Object[capacity];
	}

	public boolean isEmpty() {
		return availableItems.availablePermits() == 0;
	}

	public boolean isFull() {
		return availableSpaces.availablePermits() == 0;
	}

	public void put(E x) throws InterruptedException {
		if (availableSpaces.tryAcquire(2, TimeUnit.SECONDS)) {
			System.out.println("availableSpaces acquire");
			System.out.println("available Spaces="+availableSpaces.availablePermits());
			doInsert(x);
			availableItems.release();
			System.out.println("availableItems release");
			System.out.println("available Items="+availableItems.availablePermits());
		} else {
			System.out.println("time out.");
		}
	}

	public E take() throws InterruptedException {
		// availableItems.acquire();
		if (availableItems.tryAcquire(2, TimeUnit.SECONDS)) {
			System.out.println("availableItems acquire");
			System.out.println("available Items="+availableItems.availablePermits());
			E item = doExtract();
			availableSpaces.release();
			System.out.println("availableSpaces release");
			System.out.println("available Spaces="+availableSpaces.availablePermits());
			return item;
		} else {
			System.out.println("time out.");
			return null;
		}
	}

	private synchronized void doInsert(E x) {
		int i = putPosition;
		items[i] = x;
		putPosition = (++i == items.length) ? 0 : i;
		System.out.println("insert " + x);
	}

	private synchronized E doExtract() {
		int i = takePosition;
		E x = items[i];
		items[i] = null;
		takePosition = (++i == items.length) ? 0 : i;
		System.out.println("extract " + x);
		return x;
	}

	public static void main(String[] ss) throws InterruptedException {
		final SemaphoreBoundedBuffer<Integer> buffer = new SemaphoreBoundedBuffer<Integer>(
				2);
		buffer.put(1);
		System.out.println("---- ----");
		buffer.put(2);
		System.out.println("---- ----");
		buffer.put(3);
		System.out.println("---- ----");
		buffer.take();
		System.out.println("---- ----");
		buffer.take();
		System.out.println("---- ----");
		buffer.take();
	}
}

 

Barrier 路障

它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环 的 barrier。

门闩用来等待事件,路障用来等待其他线程。

门闩当计数减到0时,执行await后的代码;路障是当await数量到达设定数量后,才继续往下执行。

例子

public class CyclicBarrierTest {
	public static void main(String[] args) throws InterruptedException,
			BrokenBarrierException {
		int count = Runtime.getRuntime().availableProcessors();
		System.out.println("available processors = " + count);

		if (count == 1)
			count = 4;

		final CyclicBarrier barrier = new CyclicBarrier(count, new Runnable() {
			@Override
			public void run() {
				System.out.println("figure out what they are doing next.");
			}
		});

		ExecutorService exec = Executors.newFixedThreadPool(count);
		while (count > 0) {
			exec.execute(new Thread(count + "") {
				public void run() {
					System.out.println(getName() + " gets McDonald");
					try {
						barrier.await();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					} catch (BrokenBarrierException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
			Thread.sleep(500);
			count--;
		}
		exec.shutdown();
	}
}
分享到:
评论

相关推荐

    麒麟虚拟机同步器1.5p版

    麒麟虚拟机同步器1.5p版是一款专为虚拟机设计的同步工具,它主要针对的是麒麟操作系统在虚拟环境下的应用。麒麟操作系统是中国自主研发的一款开源操作系统,基于Linux内核,旨在提供安全、稳定、高效的计算环境。这...

    麒麟虚拟机同步器2.2p版

    麒麟虚拟机同步器2.2p版是一款专为麒麟操作系统设计的高效虚拟机同步工具,旨在提高多虚拟机环境下的协作效率和数据一致性。这款软件能够实现不同虚拟机实例之间的实时数据同步,确保用户在各个虚拟环境中都能获取到...

    键鼠多开同步器

    "键鼠多开同步器"是一种专为游戏多开或者多任务操作设计的软件工具,它的主要功能是实现多个窗口间键盘和鼠标操作的同步。这意味着用户在一个游戏或应用程序中的输入,可以同时被其他打开的相同程序窗口所接收,极大...

    多窗口同步器

    标题中的“多窗口同步器”是一款专为提高办公效率设计的软件工具,它允许用户将桌面分割成多个独立的工作窗口,以便同时管理和操作多个应用程序或文档。这种工具尤其适合需要频繁切换窗口或进行多任务处理的用户,如...

    麒麟VM虚拟机同步器V2.2.rar

    【麒麟VM虚拟机同步器V2.2】是一款专为VMware Workstation设计的实用工具,旨在解决在多虚拟机环境中进行键盘和鼠标同步操作的问题。VMware Workstation是一款强大的桌面虚拟化软件,允许用户在同一台物理主机上运行...

    多窗口操作同步器v1.3.zip

    《多窗口操作同步器v1.3:实现高效多任务同步处理》 在现代的多任务处理环境中,高效地管理并同步多个软件窗口的操作成为了一项挑战。"多窗口操作同步器v1.3"正是为此目的而设计的一款实用工具,它能够帮助用户在...

    超玩鼠键同步器v1.0免费绿色版

    超玩鼠键同步器是使用按键精灵制作的一款鼠键同步器,支持多窗口同步按键、鼠标动作,支持双开,支持鼠标拖拽,不支持鼠标双击、滚轮功能,一般是在游戏多开时使用,两个游戏窗口中鼠标和键盘的操作完全两步 ...

    学习游戏脚本制作:按键精灵键鼠同步器源码分享.pdf

    学习游戏脚本制作:按键精灵键鼠同步器源码分享 本文主要讲解了学习游戏脚本制作中的按键精灵键鼠同步器的实现原理和具体实现步骤。按键精灵键鼠同步器是游戏同步的重要组件,它可以实现在两个窗口之间的键鼠同步。...

    单bit信号跨时钟域的方法:电平同步器+边沿同步器+脉冲同步器

    为了解决这个问题,有几种同步技术被广泛使用,包括电平同步器、边沿同步器和脉冲同步器。以下将详细讨论这些同步器的工作原理、设计方法以及它们在Verilog中的实现。 首先,电平同步器(Level Synchronizer)是最...

    窗口同步器

    窗口同步器是一种软件工具,它的主要功能是在多个窗口或实例之间实现操作的同步。这个工具尤其适用于需要同时处理多个相同程序或应用的工作场景,比如在编程、数据分析、文本编辑或者多任务管理时。通过窗口同步器,...

    异步输入的同步器和开关防颤电路的设计

    在电子工程领域,异步输入的同步器和开关防颤电路是两个重要的概念,它们在数字逻辑系统,尤其是微控制器和嵌入式系统的设计中扮演着关键角色。本篇文章将详细探讨这两个概念,并以4位二进制计数器的设计为例,阐述...

    帧同步器设计

    帧同步器设计是数字通信系统中的重要组成部分,它在接收端恢复发送端的帧边界,确保数据正确解码。在清华大学电子工程系的数字逻辑与处理器基础实验中,学生将学习如何设计这样的系统,特别是在FPGA(Field-...

    HellX 局域网键鼠同步器.rar

    《HellX 局域网键鼠同步器:开启多游戏操控新纪元》 在现代电子竞技和游戏娱乐中,玩家往往需要同时操作多个游戏,无论是为了比较不同游戏的体验,还是进行多开游戏的策略,这样的需求日益增长。这时,一款名为...

    Romax专题培训——同步器建模与分析.pdf

    同步器建模与分析是汽车传动系统设计中的一个重要环节,尤其是在手动变速箱设计中,同步器的作用是确保换挡平顺,避免齿轮碰撞。Romax作为一款专业的传动系统设计和分析软件,提供了强大的同步器建模与分析功能。在...

    网络时间同步器.rar

    《网络时间同步器详解》 在数字化社会中,时间的准确性对于各种系统和服务的正常运行至关重要。网络时间同步器就是确保设备时间精确无误的重要工具。本文将详细探讨网络时间同步器的概念、工作原理以及其在实际应用...

    网络时间同步器(秒杀)

    网络时间同步器是一种重要的工具,尤其在网络环境中的各种操作中,准确的时间同步是至关重要的。在秒杀活动中,网络时间的精确性对于确保公平公正至关重要,因为抢购往往依赖于毫秒级的时间精度来决定谁是第一个提交...

    风云时间同步器V1.1

    风云时间同步器V1.1是一款专为用户设计的实用工具,旨在帮助用户轻松地将他们的计算机时钟与网络上的标准时间服务器进行同步,确保电脑时间的准确无误。时间同步对于日常计算机操作、网络通信以及某些特定应用程序的...

    好人多窗口同步器

    好人多窗口同步器!

    源码_C#_雷电中控与手机同步器开源

    【标题】"源码_C#_雷电中控与手机同步器开源"涉及的主要知识点是C#编程语言在实现跨平台设备控制与同步中的应用,特别是与雷电模拟器的集成。C#是一种广泛用于构建桌面、Web以及移动应用程序的强大语言,由微软公司...

    游戏操作同步器,游戏多窗口同步工具

    游戏操作同步器,游戏多窗口同步工具,可以游戏多开,然后同步鼠标、键盘操作。 打开游戏客户端后,打开本软件,然后拖动图标选择游戏窗口,将需要同步的游戏窗口都拖到软件界面后,设置主控制游戏窗口,然后开启...

Global site tag (gtag.js) - Google Analytics