JAVA多线程之——Semaphore
来源:互联网 发布:android 彩票app源码 编辑:程序博客网 时间:2024/05/18 03:12
Semaphore
一个计数信号量。从概念上讲,信号量维护了一个许可集。如有必要,在许可可用前会阻塞每一个 acquire(),然后再获取该许可。每个 release() 添加一个许可,从而可能释放一个正在阻塞的获取者。但是,不使用实际的许可对象,Semaphore 只对可用许可的号码进行计数,并采取相应的行动。
其实Semaphore就是维护了一个共享锁,通过state来决定同时可以多少个线程获取共享锁。
public void acquire() throws InterruptedException { sync.acquireSharedInterruptibly(1);}
acquire就是获取共享锁。
acquireSharedInterruptibly
public final void acquireSharedInterruptibly(int arg) throws InterruptedException { if (Thread.interrupted()) //线程被中断抛出中断异常 throw new InterruptedException(); if (tryAcquireShared(arg) < 0) //尝试获取锁 doAcquireSharedInterruptibly(arg);//调用方法doAcquireSharedInterruptibly }
doAcquireSharedInterruptibly
private void doAcquireSharedInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.SHARED);//// 创建”当前线程“的Node节点,且Node中记录的锁是”共享锁“类型;并将该节点添加到CLH队列末尾。 boolean failed = true; try { for (;;) { final Node p = node.predecessor(); //获取前一个节点 if (p == head) { //如果上一个节点是头节点 int r = tryAcquireShared(arg);//尝试获取锁(上一个是头节点,那么可能此时上一个节点已经成功获取了锁,所以尝试获取一下) if (r >= 0) { //获取成功 setHeadAndPropagate(node, r); //设置头节点 p.next = null; // help GC failed = false; return; } } // 当前线程一直等待,直到获取到共享锁。 // 如果线程在等待过程中被中断过,则再次中断该线程(还原之前的中断状态)。 if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) throw new InterruptedException(); } } finally { if (failed) cancelAcquire(node); } }
因此Semaphore就是同时可以让多个线程去获取共享锁,如果线程达到指定阀值,那么就等待,一直等到其它线程调用了release释放。
所以,Semaphore经常用来控制公共资源的并发访问。比如对某一个文件限制只能同时10个线程进行读取。
public class SemaphoreTest { static Semaphore semaphore = new Semaphore(10); public static void main(String[] args) { for(int i = 0 ; i < 100; i++) { new ReadFile().start(); } } static class ReadFile extends Thread{ @Override public void run() { try { semaphore.acquire(); System.out.println(Thread.currentThread().getName() + "开始读取文件"); Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); }finally{ // System.out.println(Thread.currentThread().getName() + "释放了一个许可"); //semaphore.release(); } } }}
某次运行结果:
Thread-0开始读取文件Thread-1开始读取文件Thread-4开始读取文件Thread-2开始读取文件Thread-3开始读取文件Thread-5开始读取文件Thread-7开始读取文件Thread-9开始读取文件Thread-6开始读取文件Thread-8开始读取文件
结果是只有是个线程开始读取,其它线程都在等待,没有打印出来。如果把上面的注释代码去掉。那么有释放锁,就会让其它线程可以读取。
0 0
- JAVA多线程之——Semaphore
- Java多线程之Semaphore
- JAVA多线程之Semaphore
- Java多线程之Semaphore
- Java多线程之Semaphore
- Java多线程——Semaphore
- Java多线程之信号量Semaphore
- Java 多线程之信号量 Semaphore
- (八)java多线程之Semaphore
- JAVA多线程—Semaphore实现信号灯
- 关于Java多线程和并发运行的学习(四)——之Semaphore
- Java多线程之concurrent包(四)——Semaphore信号量
- java多线程之Semaphore信号量详解
- java多线程同步工具之Semaphore信号灯
- 我之见--java多线程信号量Semaphore
- java多线程之Semaphore类基本用法
- java多线程之Semaphore信号量详解
- java 多线程之Semaphore互斥类的用法
- 安卓多媒体应用-通知
- about unity3d freeze packaging assets sharedassets0.assets
- archlinux安装个简单桌面icewm
- prompt(1) to win writeup
- RecyclerView添加头部(addHeaderView)和脚部(addFooterView)的封装
- JAVA多线程之——Semaphore
- 因为 MyEclipse 和jdk不匹配问题
- 历届试题 回文数字
- 练习
- Java中的构造方法
- python基础知识之逗号输出、赋值
- python写map,reduce访问集群文件
- Activity启动流程分析
- 弹出菜单的创建与使用