文档章节

java Semaphore-信号灯机制

qimh
 qimh
发布于 2018/03/30 16:36
字数 818
阅读 301
收藏 0

当我们创建一个可扩展大小的线程池,并且需要在线程池内同时让有限数目的线程并发运行时,就需要用到Semaphore(信号灯机制),Semaphore 通常用于限制可以访问某些资源(物理或逻辑的)的线程数目,它是一个计数信号量,从概念上讲,信号量维护了一个许可集合,如有必要,在许可可用前会阻塞每一个acquire(),然后再获取该许可,每个release() 添加一个许可,从而可能释放一个正在阻塞的获取者。        

 代码如下:

package com.qimh.concurrent;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Semaphore;

public class SemahoreDemo {

	public static void main(String[] args) {  
        ExecutorService service = Executors.newCachedThreadPool();  
        final  Semaphore sp = new Semaphore(3);//定义有3个信号灯  
        for(int i=0;i<5;i++){  
            Runnable runnable = new Runnable(){  
                    public void run(){  
                    	 System.out.println("线程" + Thread.currentThread().getName() +"   " + System.currentTimeMillis());
                    try {  
                        sp.acquire();  
                    } catch (InterruptedException e1) {  
                        e1.printStackTrace();  
                    }  
                    //sp.availablePermits()指的是当前信号灯库中有多少个可以被使用
                    System.out.println("线程" + Thread.currentThread().getName() +   
                            "进入,当前已有" + (3-sp.availablePermits()) + "个并发" + "---"+sp.availablePermits() + "    " +System.currentTimeMillis()); //3-sp.availablePermits()就代表了当前有多少个线程在并发运行
                    try {  
                        Thread.sleep((long)(Math.random()*10000));  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                    System.out.println("线程" + Thread.currentThread().getName() +   
                            "即将离开");                      
                    sp.release();  
                    //下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元  
                    System.out.println("线程" + Thread.currentThread().getName() +   
                            "已离开,当前已有" + (3-sp.availablePermits()) + "个并发");  
                }  
            };  
            service.execute(runnable);            
        }  
        
        
        service.shutdown();
    }    

}

 

代码解析:

 该例子定义了一个newCachedThreadPool,在该Pool中利用for循环同时创建5个线程,现在通过Semaphore,创建一个只允许在线程池中有3个线程并发运行,sp.acquire()表示某个线程获得了一个信号灯,开始运行,在运行结束时,通过sp.release()还回这个信号灯,以便剩下的线程获得信号灯运行,sp.availablePermits()指的是当前信号灯库中有多少个可以被使用,由于例子中定义有3个信号灯,所以3-sp.availablePermits()就代表了当前有多少个线程在并发运行,上例运行结果如下:

线程pool-1-thread-1   1522397840180
线程pool-1-thread-1进入,当前已有1个并发---2    1522397840181
线程pool-1-thread-4   1522397840181
线程pool-1-thread-4进入,当前已有2个并发---1    1522397840181
线程pool-1-thread-3   1522397840181
线程pool-1-thread-3进入,当前已有3个并发---0    1522397840181
线程pool-1-thread-2   1522397840180
线程pool-1-thread-5   1522397840181
线程pool-1-thread-4即将离开
线程pool-1-thread-4已离开,当前已有2个并发
线程pool-1-thread-2进入,当前已有3个并发---0    1522397841645
线程pool-1-thread-1即将离开
线程pool-1-thread-1已离开,当前已有2个并发
线程pool-1-thread-5进入,当前已有3个并发---0    1522397845323
线程pool-1-thread-2即将离开
线程pool-1-thread-2已离开,当前已有2个并发
线程pool-1-thread-3即将离开
线程pool-1-thread-3已离开,当前已有1个并发
线程pool-1-thread-5即将离开
线程pool-1-thread-5已离开,当前已有0个并发

参考链接:https://blog.csdn.net/zzp_403184692/article/details/8017173

                 https://blog.csdn.net/u011613354/article/details/51150248

© 著作权归作者所有

qimh
粉丝 10
博文 485
码字总数 88751
作品 0
滁州
程序员
私信 提问
加载中

评论(0)

PV操作和信号量机制实现进程同步(对多个临界资源的互斥访问)

进程同步是我们在多线程中讨论最多的一个话题,在大多数的开发语言中,他们都有自己实现进程同步的方法或者实现。但归根结底他们实现的方式都是基于操作系统的进程同步的方式。今天我们就一起...

长平狐
2012/11/12
869
0
Ignite.NET插件示例:分布式Semaphore(信号量)

Ignite.NET从2.0版本开始,引入了插件系统,插件可以仅在于.NET环境中,也可以在于.NET + Java混合环境中,本文会描述如何在后者实现插件。 为什么需要插件? Ignite.NET构建于Ignite(用Jav...

李玉珏
2019/11/01
122
0
4种常用Java线程锁的特点,性能比较及使用场景

多个线程同时对同一个对象进行读写操作,很容易会出现一些难以预料的问题。所以很多时候我们需要给代码块加锁,同一时刻只允许一个线程对某个对象进行操作。多线程之所以会容易引发一些难以发现...

mikechen优知
2019/03/10
273
0
JUC锁框架——Semaphore

Semaphore简单介绍 Semaphore是计数信号量。Semaphore管理一系列许可证。每个acquire方法阻塞,直到有一个许可证可以获得然后拿走一个许可证;每个release方法增加一个许可证,这可能会释放一...

长头发-dawn
2018/09/17
38
0
111 多线程JUC包下代码分析

Java多线程系列目录(共43篇) AtomicLongFieldUpdater:通过反射+CAS实现对传入对象的指定long字段实现类似AtomicLong的操作 http://www.cnblogs.com/skywang12345/p/javathreadscategory.ht...

素雷
2017/10/31
64
0

没有更多内容

加载失败,请刷新页面

加载更多

Elasticsearch:shard 分配感知

osc_lnhxmt4i
10分钟前
8
0
Elasticsearch:分布式计分

osc_rnx2cje5
12分钟前
11
0
vue-element-admin中public中json中的代码没有打包到线上

解决的办法 将public中的文件放到static中,修改对应的路径,就可以解决这个bug了

osc_8hhlaimy
15分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部