网上关于解释Semaphore用法的代码很多,但是都不能运行或者运行错误。下面的例子是经过我自己运行过的。而且我详细的注释了下各个变量和方法的用途。希望对大家有用,一起研究。
import java.util.concurrent.Semaphore;
/**
*
* @author Administrator
*
*/
public class PoolSemaphoreDemo {
private static final int MAX_AVAILABLE = 5;
private final Semaphore available = new Semaphore(MAX_AVAILABLE, true);
public static void main(String[] args) {
final PoolSemaphoreDemo pool = new PoolSemaphoreDemo();
Runnable runner = new Runnable() {
public void run() {
try {
Object o;
o = pool.getItem();
Thread.sleep(1000);// 表示该线程睡眠1秒钟,即改线程不去竞争cpu处理时间1秒钟
pool.putItem(o);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
// 将上述线程重复执行10次
for (int i = 0; i < 10; i++) {
Thread t = new Thread(runner, "t" + i);
t.start();
}
}
/**
* 从字符串池中取得最近一个可用的字符串资源,同时将标志位池中的状态设为true,表示有线程正在使用。
*
* @return
* @throws InterruptedException
*/
public Object getItem() throws InterruptedException {
System.out.println("线程:" + Thread.currentThread().getName()
+ "开始从字符串资源池中取数据");
available.acquire();
return getNextAvailableItem();
}
/**
* 将x对应的标志位池的状态修改为false,然后释放改字符串资源供其他线程读取
*
* @param x
*/
public void putItem(Object x) {
if (markAsUnused(x)) {
available.release();
System.out.println("线程:" + Thread.currentThread().getName()
+ "已经释放资源");
}
}
// 需要循环取的字符串池
protected Object[] items = { "AAA", "BBB", "CCC", "DDD", "EEE" };
// 字符串池对应的标志位池,如果为true表示正在使用,其他线程不可用。如果为false,则表示其他线程可以用
protected boolean[] used = new boolean[MAX_AVAILABLE];
/**
* 根据标志位数组得到items中有效的字符串
*
* @return
*/
protected synchronized Object getNextAvailableItem() {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (!used[i]) {
used[i] = true;
System.out.println("线程:" + Thread.currentThread().getName()
+ "从字符串池中取得资源:" + items[i]);
return items[i];
}
}
return null;
}
/**
* 根据item将对应位置的标志位的值改为false
*
* @param item
* @return
*/
protected synchronized boolean markAsUnused(Object item) {
for (int i = 0; i < MAX_AVAILABLE; ++i) {
if (item == items[i]) {
if (used[i]) {
used[i] = false;
System.out.println("线程:" + Thread.currentThread().getName()
+ "开始向字符串池中放入资源:" + items[i]);
return true;
} else
return false;
}
}
return false;
}
}
Semaphore的用途中需要注意的就是,当release()或者acquire()时,如果当前线程不能获取到资源,那么当前线程会阻塞。知道获取到资源为止,这点可以从输出结果中可以看到。
下面是运行结果
线程:t0开始从字符串资源池中取数据
线程:t0从字符串池中取得资源:AAA
线程:t1开始从字符串资源池中取数据
线程:t1从字符串池中取得资源:BBB
线程:t3开始从字符串资源池中取数据
线程:t3从字符串池中取得资源:CCC
线程:t5开始从字符串资源池中取数据
线程:t5从字符串池中取得资源:DDD
线程:t7开始从字符串资源池中取数据
线程:t7从字符串池中取得资源:EEE
线程:t9开始从字符串资源池中取数据
线程:t2开始从字符串资源池中取数据
线程:t4开始从字符串资源池中取数据
线程:t6开始从字符串资源池中取数据
线程:t8开始从字符串资源池中取数据
线程:t0开始向字符串池中放入资源:AAA
线程:t0已经释放资源
线程:t9从字符串池中取得资源:AAA
线程:t1开始向字符串池中放入资源:BBB
线程:t1已经释放资源
线程:t3开始向字符串池中放入资源:CCC
线程:t3已经释放资源
线程:t2从字符串池中取得资源:BBB
线程:t4从字符串池中取得资源:CCC
线程:t5开始向字符串池中放入资源:DDD
线程:t5已经释放资源
线程:t7开始向字符串池中放入资源:EEE
线程:t7已经释放资源
线程:t6从字符串池中取得资源:DDD
线程:t8从字符串池中取得资源:EEE
线程:t9开始向字符串池中放入资源:AAA
线程:t9已经释放资源
线程:t4开始向字符串池中放入资源:CCC
线程:t4已经释放资源
线程:t2开始向字符串池中放入资源:BBB
线程:t2已经释放资源
线程:t8开始向字符串池中放入资源:EEE
线程:t8已经释放资源
线程:t6开始向字符串池中放入资源:DDD
线程:t6已经释放资源
分享到:
相关推荐
多线程编程:信号量使用。 打包文件包含两个文件:c文件源代码、Makefile文件,运行环境在Ubuntu14.04下,使用自带的gcc编译器,同学们只需将文件夹复制到某一目录下之后在终端执行:1.“make”生成“test”可执行...
多线程(C++)同步Semaphore
Linux下多线程编程-Pthread与Semaphore的使用.doc
主要介绍了JAVA 多线程之信号量(Semaphore)实例详解的相关资料,需要的朋友可以参考下
JAVA多线程--信号量(Semaphore)_.docx
Java多线程Semaphore工具的使用详解.rar
主要参考资料:java并发编程的艺术、Java并发——同步工具类 二、CountDownLatch(同步倒数计数器)–不仅仅用于多线程 1.作用:允许一个或多个线程等待其他线程完成操作。 CountDownLatch的构造函数...
同步控制是并发程序必不可少的重要手段,本文我们将通过重入锁、读写锁、信号量、倒计数器和循环栅栏以及他们的实例来介绍Java并发程序中的同步控制。 目录线程安全 Thread Safety重入锁 ReentrantLock读写锁 ...
Java 5.0里新加了4个协调线程间进程的同步装置,它们分别是Semaphore, CountDownLatch, CyclicBarrier和Exchanger,本例主要介绍Semaphore,Semaphore是用来管理一个资源池的工具,可以看成是个通行证
c: 多线程访问同一资源 d: 经典线程同步互斥问题 e: 使用关键段解决子线程互斥问题 f: 利用事件实现线程同步问题 g: 利用互斥量来解决线程同步互斥问题 h: problem1 生产者消费者问题 (1生产者 1消费者 1...
使用信号量(Semaphore)实现线程的同步
主要介绍了Java多线程同步器代码详解,文章分别介绍了是CountDownLatch,Semaphore,Barrier和Exchanger以及其相关代码示例,具有一定参考价值,需要的朋友可以了解下。
一、多线程同步 由于CPython的python解释器在单线程模式下执行,所以导致python的多线程在很多的时候并不能很好地发挥多核cpu的资源。大部分情况都推荐使用多进程。 python的多线程的同步与其他语言基本相同,主要...
看完《think in java》多线程章节,自己写的多线程文档,还结合了其他的相关网络资料。 线程 一. 线程池 1)为什么要使用线程池 2 2)一个具有线程池的工作队列 3 3)使用线程池的风险: 4 4)有效使用线程池的原则 5...
Java并发编程的核心概念包括: 线程(Thread):线程是程序执行流的最小单元。...原子操作(Atomic Operations):原子操作是不可中断的操作,即在多线程环境中,这些操作要么完全执行,要么完全不执行。
java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+Semaphore+Exchanger);java并发工具类(CountDownLatch+...
semaphore控制多线程循序执行,网上 找的例子更改的希望对大家有用
『死磕Java并发编程系列』 01 十张图告诉你多线程那些破事 『死磕Java并发编程系列』 02 面试官:说说什么是Java内存模型? 『死磕Java并发编程系列』 03 面试必问的CAS原理你会了吗? 『死磕Java并发编程系列』 04 ...
内容概要:最新2023年Java高并发多线程后端面试题整理, 包含线程池,并发集合,volatile,CountDownLatch,Semaphore,Phaser,AQS,ReentrantLock,ReentrantLock等等问题, 用简洁明了的语言,通俗易懂地阐述了高...
.NET多线程同步方法详解(一):自由锁(InterLocked) 本文主要描述在C#中线程同步的方法。线程的基本概念网上资料也很多就不再赘述了。直接接入主题,在多线程开发的应用中,线程同步是不可避免的。在.Net框架中,...