技术信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者执行某个特定操作的数量。计数信号量还可以用来实现某种资源池或者对容器加边界。
Semaphore中管理着一组虚拟许可(permit),许可的初始数量可以通过在构造方法中指定。在执行操作时首先获取许可(permit),在使用完成后释放许可。如果没有许可,那么acquire则一直阻塞到有许可或者超时中断。
/** * 计数信号量(Counting Semaphore)用来控制同时访问某个特定资源的操作数量,或者执行某个指定操作的数量。 * 计数信号量还可以用来实现某种资源池或者对容器进行加边界 * Semaphore 中管理着一组虚拟的许可(permit),许可的初始化数量可以通过构造函数来指定。在执行操作时可以 * 首先获取许可(只要还有剩余的许可),并在使用后释放许可(permit)。 如果没有许可(permit)那么aquire将阻塞 * 直到有许可或者直到被中断、操作超时。release方法将释放一个许可,返回给信号量(semaphore) * * @author zhangwei_david * @version $Id: BoundedHashSet.java, v 0.1 2014年11月11日 下午1:49:24 zhangwei_david Exp $ */ public class BoundedHashSet<T> { // private final Set<T> set; // 信号量 private final Semaphore sem; public BoundedHashSet(int bound) { //初始化一个同步Set this.set = Collections.synchronizedSet(new HashSet<T>()); //初始化信号量大小 sem = new Semaphore(bound); } public boolean add(T o) throws InterruptedException { // 获取许可 sem.acquire(); System.out.println("获取许可 " + sem.availablePermits()); boolean wasAdded = false; try { wasAdded = set.add(o); return wasAdded; } finally { if (!wasAdded) { // 如果增加失败 System.out.println("添加失败,释放许可"); sem.release(); } } } public boolean remove(Object o) { boolean wasRemoved = set.remove(o); if (wasRemoved) { // 删除后释放许可 System.out.println("删除成功,释放许可"); sem.release(); } return wasRemoved; } }
/** * 资源池 * @author zhangwei_david * @version $Id: ResourcePool.java, v 0.1 2015年7月5日 上午9:53:18 zhangwei_david Exp $ */ public class ResourcePool<T> { private int size; private List<T> items = new ArrayList<T>(); private volatile boolean[] checkOut; private Semaphore available; public ResourcePool(Class<T> clazz, int max) { size = max; checkOut = new boolean[size]; available = new Semaphore(size); for (int i = 0; i < size; i++) { try { items.add(clazz.newInstance()); } catch (Exception e) { e.printStackTrace(); } } } public T checkOut() throws InterruptedException { available.acquire(); return getItem(); } public void checkIn(T t) { if (releaseItem(t)) { available.release(); } } /** * 释放对象,如果该对象在对象池中不存在则返回false * 如果该对象尚未被checkOut则返回fasle * 将checkOut标准置为false,返回true * * @param t * @return */ private synchronized boolean releaseItem(T t) { int index = items.indexOf(t); if (index == -1) { return false; } if (checkOut[index]) { checkOut[index] = false; return true; } return false; } /**6 * 如果还有对象没有checkOut则返回该对象,如果没有则返回null * * @return */ private synchronized T getItem() { for (int i = 0; i < size; i++) { if (!checkOut[i]) { checkOut[i] = true; return items.get(i); } } return null; } }
/** * * @author zhangwei_david * @version $Id: Link.java, v 0.1 2015年7月5日 上午10:11:03 zhangwei_david Exp $ */ public class Link { private static int counter = 0; private final int id = counter++; public Link() { try { TimeUnit.MILLISECONDS.sleep(300); } catch (Exception e) { } } /** * @see java.lang.Object#toString() */ @Override public String toString() { return "Link [ id=" + id + "]"; } }
/** * * @author zhangwei_david * @version $Id: SemaphoreDemo.java, v 0.1 2015年7月5日 上午10:20:16 zhangwei_david Exp $ */ public class SemaphoreDemo { /** * * @param args */ public static void main(String[] args) { final ResourcePool<Link> linkes = new ResourcePool<Link>(Link.class, 30); ExecutorService exec = Executors.newCachedThreadPool(); for (int i = 0; i < 60; i++) { exec.execute(new CheckOutTask<Link>(linkes)); } exec.shutdown(); } }
CheckOutTask [id=0] check out Link [ id=0] CheckOutTask [id=1] check out Link [ id=1] CheckOutTask [id=3] check out Link [ id=2] CheckOutTask [id=2] check out Link [ id=3] CheckOutTask [id=4] check out Link [ id=4] CheckOutTask [id=6] check out Link [ id=5] CheckOutTask [id=5] check out Link [ id=6] CheckOutTask [id=7] check out Link [ id=7] CheckOutTask [id=8] check out Link [ id=8] CheckOutTask [id=9] check out Link [ id=9] CheckOutTask [id=10] check out Link [ id=10] CheckOutTask [id=11] check out Link [ id=11] CheckOutTask [id=12] check out Link [ id=12] CheckOutTask [id=13] check out Link [ id=13] CheckOutTask [id=14] check out Link [ id=14] CheckOutTask [id=15] check out Link [ id=15] CheckOutTask [id=16] check out Link [ id=16] CheckOutTask [id=17] check out Link [ id=17] CheckOutTask [id=18] check out Link [ id=18] CheckOutTask [id=19] check out Link [ id=19] CheckOutTask [id=20] check out Link [ id=20] CheckOutTask [id=21] check out Link [ id=21] CheckOutTask [id=22] check out Link [ id=22] CheckOutTask [id=23] check out Link [ id=23] CheckOutTask [id=24] check out Link [ id=24] CheckOutTask [id=25] check out Link [ id=25] CheckOutTask [id=26] check out Link [ id=26] CheckOutTask [id=27] check out Link [ id=27] CheckOutTask [id=28] check out Link [ id=28] CheckOutTask [id=29] check out Link [ id=29] CheckOutTask [id=2] check in Link [ id=3] CheckOutTask [id=1] check in Link [ id=1] CheckOutTask [id=3] check in Link [ id=2] CheckOutTask [id=4] check in Link [ id=4] CheckOutTask [id=31] check out Link [ id=1] CheckOutTask [id=30] check out Link [ id=2] CheckOutTask [id=32] check out Link [ id=3] CheckOutTask [id=33] check out Link [ id=4] CheckOutTask [id=0] check in Link [ id=0] CheckOutTask [id=34] check out Link [ id=0] CheckOutTask [id=10] check in Link [ id=10] CheckOutTask [id=15] check in Link [ id=15] CheckOutTask [id=18] check in Link [ id=18] CheckOutTask [id=12] check in Link [ id=12] CheckOutTask [id=16] check in Link [ id=16] CheckOutTask [id=14] check in Link [ id=14] CheckOutTask [id=19] check in Link [ id=19] CheckOutTask [id=5] check in Link [ id=6] CheckOutTask [id=7] check in Link [ id=7] CheckOutTask [id=9] check in Link [ id=9] CheckOutTask [id=17] check in Link [ id=17] CheckOutTask [id=37] check out Link [ id=7] CheckOutTask [id=36] check out Link [ id=6] CheckOutTask [id=35] check out Link [ id=10] CheckOutTask [id=8] check in Link [ id=8] CheckOutTask [id=40] check out Link [ id=14] CheckOutTask [id=6] check in Link [ id=5] CheckOutTask [id=42] check out Link [ id=15] CheckOutTask [id=43] check out Link [ id=5] CheckOutTask [id=44] check out Link [ id=16] CheckOutTask [id=47] check out Link [ id=17] CheckOutTask [id=45] check out Link [ id=18] CheckOutTask [id=13] check in Link [ id=13] CheckOutTask [id=11] check in Link [ id=11] CheckOutTask [id=26] check in Link [ id=26] CheckOutTask [id=55] check out Link [ id=13] CheckOutTask [id=53] check out Link [ id=19] CheckOutTask [id=56] check out Link [ id=26] CheckOutTask [id=27] check in Link [ id=27] CheckOutTask [id=41] check out Link [ id=8] CheckOutTask [id=39] check out Link [ id=12] CheckOutTask [id=38] check out Link [ id=9] CheckOutTask [id=54] check out Link [ id=27] CheckOutTask [id=52] check out Link [ id=11] CheckOutTask [id=24] check in Link [ id=24] CheckOutTask [id=25] check in Link [ id=25] CheckOutTask [id=23] check in Link [ id=23] CheckOutTask [id=57] check out Link [ id=23] CheckOutTask [id=58] check out Link [ id=24] CheckOutTask [id=50] check out Link [ id=25] CheckOutTask [id=22] check in Link [ id=22] CheckOutTask [id=21] check in Link [ id=21] CheckOutTask [id=59] check out Link [ id=21] CheckOutTask [id=20] check in Link [ id=20] CheckOutTask [id=46] check out Link [ id=22] CheckOutTask [id=51] check out Link [ id=20] CheckOutTask [id=29] check in Link [ id=29] CheckOutTask [id=49] check out Link [ id=29] CheckOutTask [id=28] check in Link [ id=28] CheckOutTask [id=48] check out Link [ id=28] CheckOutTask [id=30] check in Link [ id=2] CheckOutTask [id=33] check in Link [ id=4] CheckOutTask [id=32] check in Link [ id=3] CheckOutTask [id=31] check in Link [ id=1] CheckOutTask [id=34] check in Link [ id=0] CheckOutTask [id=45] check in Link [ id=18] CheckOutTask [id=37] check in Link [ id=7] CheckOutTask [id=36] check in Link [ id=6] CheckOutTask [id=40] check in Link [ id=14] CheckOutTask [id=42] check in Link [ id=15] CheckOutTask [id=35] check in Link [ id=10] CheckOutTask [id=43] check in Link [ id=5] CheckOutTask [id=47] check in Link [ id=17] CheckOutTask [id=44] check in Link [ id=16] CheckOutTask [id=59] check in Link [ id=21] CheckOutTask [id=46] check in Link [ id=22] CheckOutTask [id=50] check in Link [ id=25] CheckOutTask [id=58] check in Link [ id=24] CheckOutTask [id=57] check in Link [ id=23] CheckOutTask [id=54] check in Link [ id=27] CheckOutTask [id=52] check in Link [ id=11] CheckOutTask [id=38] check in Link [ id=9] CheckOutTask [id=39] check in Link [ id=12] CheckOutTask [id=56] check in Link [ id=26] CheckOutTask [id=41] check in Link [ id=8] CheckOutTask [id=53] check in Link [ id=19] CheckOutTask [id=55] check in Link [ id=13] CheckOutTask [id=48] check in Link [ id=28] CheckOutTask [id=49] check in Link [ id=29] CheckOutTask [id=51] check in Link [ id=20]
相关推荐
在Java多线程编程中,信号量Semaphore是一种非常重要的同步工具,用于控制对公共资源的访问。Semaphore类位于`java.util.concurrent`包下,它允许我们限制同时访问特定资源的线程数量。 ### Semaphore简介 信号量...
JAVA多线程--信号量(Semaphore) 信号量(Semaphore)是一种多线程环境下的设施,负责协调各个线程,以保证它们能够正确、合理地使用公共资源。从概念上讲,信号量维护了一个许可集。 信号量的类型有两种:单值信号...
Java提供了多种同步工具,如synchronized关键字、wait()和notify()方法、Lock接口(包括ReentrantLock可重入锁)以及Semaphore信号量等。这些工具能够确保共享资源在多线程访问时的安全性,防止数据竞争和死锁的发生...
在多线程编程中,当多个线程试图同时访问一个有限的资源时,信号量可以帮助我们协调这些线程,确保资源的有序分配和释放。 信号量主要由两个操作组成:`P(Wait)操作`和`V(Signal)操作`。这两个操作通常被封装在...
### Java多线程编程总结 #### 一、Java线程:概念与原理 1. **操作系统中线程和进程的概念** - 当前的操作系统通常为多任务操作系统,多线程是实现多任务的一种手段。 - **进程**:指内存中运行的应用程序,每个...
RedSpider社区的这个压缩包“多线程精品资源”显然是一个集合了社区成员原创和维护的关于Java多线程的系列文章,旨在帮助开发者深入理解和掌握多线程的核心概念及实践技巧。 1. **线程基础** - **线程的定义**:...
Java多线程实战精讲是Java开发者必备的技能之一,特别是在处理高并发场景时,它的重要性不言而喻。本文将深入探讨Java多线程的相关知识点,帮助你全面理解并掌握这一核心概念。 1. **线程基础** - **线程定义**:...
- Semaphore:信号量,控制同时访问特定资源的线程数量。 - Phaser:更强大的同步工具,支持分阶段的同步。 7. **死锁、活锁与饥饿** - 死锁:两个或多个线程相互等待对方释放资源,导致都无法继续执行。 - ...
### Java多线程运算集合知识点解析 #### 一、Java多线程概念与原理 - **操作系统中的线程与进程**: - **进程**:指的是一个正在运行的应用程序,每个进程都拥有独立的内存空间。 - **线程**:是进程中的一个...
- JUC包含了许多高级并发组件,如`Semaphore`信号量、`CyclicBarrier`回环栅栏、`CountDownLatch`倒计时器和`Exchanger`交换器等,它们可以帮助控制线程的执行顺序。 - `Semaphore`可以限制同时访问特定资源的线程...
本书还涉及到了Java并发工具类,如Semaphore信号量、CyclicBarrier栅栏、CountDownLatch倒计时器等,这些都是Java并发编程中的重要工具,可以帮助开发者更精细地控制线程执行。另外,书中还会介绍如何使用Future和...
Java提供了多种同步机制,如synchronized关键字、Lock接口(ReentrantLock、ReentrantReadWriteLock)以及Semaphore信号量。synchronized用于方法或代码块,可以保证同一时间只有一个线程执行特定代码,避免数据冲突...
在"semaphore控制多线程循序执行"的场景中,我们通常会用到计数信号量,它的核心作用是限制同时访问特定资源的线程数量。例如,如果我们要实现一个打印队列,让多个线程按顺序打印任务,Semaphore就可以用来保证打印...
- `Semaphore`信号量:控制同时访问特定资源的线程数量。 - `CyclicBarrier`循环栅栏:允许一组线程等待彼此到达某个点,然后一起继续。 - `CountDownLatch`计数器门锁:一次性释放所有等待线程,常用于初始化...
- **Semaphore**:信号量,控制同时访问特定资源的线程数量。 - **ThreadPoolExecutor**:线程池,管理线程并处理任务队列,能有效控制运行的线程数量。 5. **文件传输** - **I/O流**:Java的`InputStream`和`...
Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,实现多线程有两种主要方式:通过继承`Thread`类或者实现`Runnable`接口。 1. **继承Thread类*...
- **线程同步**:包括`synchronized`关键字、`Lock`接口(如`ReentrantLock`)、`Semaphore`信号量、`CountDownLatch`计数器和`CyclicBarrier`屏障等机制,用于控制并发访问资源的顺序和数量,防止数据竞争。...
- 了解条件变量(Condition)和信号量(Semaphore)的使用场景。 4. 线程池 - 掌握Executor框架的使用,以及如何创建和管理线程池; - 理解线程池的优势,比如提高资源利用率和降低系统开销。 5. 高级多线程...
- **Semaphore**:信号量,用于控制同时访问特定资源的线程数量,通过acquire()获取一个许可,如果没有就等待,release()释放一个许可。 4. **线程安全** - **volatile变量**:保证了内存可见性和有序性,但不...
- `Semaphore`:信号量,用于限制并发访问的线程数量。 7. **线程设计模式**: - 生产者-消费者模式:使用`BlockingQueue`实现线程间的生产与消费。 - 线程池模式:通过`ExecutorService`实现线程复用,避免频繁...