您的位置:首页 > 编程语言 > Java开发

使用信号量Semaphore循环打印ABC

2016-07-19 14:14 483 查看
最近学习了java的并发相关知识,了解了一下java.util.concurrent包,今天介绍的是concurrent包下的Semaphore,又称为信号量。

信号量主要用来控制同时访问同一资源的线程 数量,用jdk api官方的话说就是:

Semaphores are often used to restrict the number of threads than can access some (physical or logical) resource. 大意就是Semaphore是用来限制访问一些资源的线程数量,其中有两个重要的方法acquire()和release()。acquire用来获取一个信号量,并且是阻塞型的,如果当前还有可用的信号量,则获取成功,可用信号量减1,使用完后可用release释放信号量。jdk api描述如下:

A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it. Each release() adds a permit, potentially releasing a blocking acquirer.

下面将使用Semaphore实现循环打印ABC的功能,即有三个线程,线程1打印A,线程2打印B,线程3打印C,最后输出ABCABCABCABC…,相等于使用多线程实现了串行打印的功能,下一篇我将会介绍CountDownLatch及join两种方式实现并行打印的功能。

代码如下:

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

public class PrintABC {

//信号量,用于控制同时容许访问的线程数量
public Semaphore s1 = new Semaphore(1);
public Semaphore s2 = new Semaphore(0);
public Semaphore s3 = new Semaphore(0);

public static void main(String[] args) {
new PrintABC().printABC();
}

public void printABC() {
ExecutorService exe = Executors.newCachedThreadPool();
Thread t1 = new Thread(){
@Override
public void run() {
while(true) {
try {
s1.acquire();//获取信号量,s1 - 1
System.out.print("A");
s2.release();//释放信号量,s2 + 1
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};

Thread t2 = new Thread(){
@Override
public void run() {
while(true) {
try {
s2.acquire();//获取信号量,s2 - 1
System.out.print("B");
s3.release();//释放信号量,s3 + 1
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};

Thread t3 = new Thread(){
@Override
public void run() {
while(true) {
try {
s3.acquire();//获取信号量,s3 - 1
System.out.print("C");
s1.release();//释放信号量,s1 + 1
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
};

exe.execute(t1);
exe.execute(t2);
exe.execute(t3);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息