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

Java并发同步器--Semaphore

2015-12-28 19:16 567 查看
Semaphore(信号量)同步器的使用主要是完成Java多线程并发。Semaphore类是定义于concurrent工具包下的对java.io.Serializable接口的一个实现类。主要是通过Semaphore构造方法对信号量进行初始化,原型如下:

public Semaphore(int permits) {
sync = new NonfairSync(permits);
}


参数permits是初始化信号量的数目,也就是最多同时允许并发线程的数目。定义的semaphore对象常用的两种方法acquire和release定义如下:

public void acquire() throws InterruptedException {
sync.acquireSharedInterruptibly(1);
}
public void release() {
sync.releaseShared(1);
}


acquire是子线程获取信号量,而release是子线程完成任务后进行信号量的释放。semaphore同步器的原理其实很简单,获取信号量的线程进行运行,并发的线程数目由初始化的信号量决定,运行完的子线程释放信号量,其它挂起的线程会获取到释放的信号量进行运行。如下所示:

package concurrent;

import java.util.concurrent.Semaphore;

public class TestSemaphore {
public static void main(String[] args) {
'''初始化信号量的数目''
Semaphore semaphore = new Semaphore(2);
Service service1 = new Service(semaphore, "A");
service1.start();
Service service2 = new Service(semaphore, "B");
service2.start();
Service service3 = new Service(semaphore, "C");
service3.start();
Service service4 = new Service(semaphore, "D");
service4.start();
}
}
class Service extends Thread {
private Semaphore semophore;

public Service(Semaphore semaphore, String name) {
setName(name);
this.semophore = semaphore;
}

public void run() {
try {
System.out.println(getName() + "is waiting");
semophore.acquire();
System.out.println(getName() + "is working");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
System.out.println(getName() + "is done");
semophore.release();
}
}
}


程序的其中一种运行结果如下(多线程问题正常会出现多种运行结果):

Ais waiting
Cis waiting
Ais working
Bis waiting
Cis working
Dis waiting
Ais done
Bis working
Cis done
Dis working
Bis done
Dis done


可以看出,当初始化信号量的个数为2个的时候,只允许有两个线程同步处于working的状态,其它两个线程只能等到之前两个线程done之后,才能运行。若此时将信号量初始化为permits=4,运行结果如下:

Cis waiting
Ais waiting
Cis working
Bis working
Dis working
Ais working
Cis done
Ais done
Bis done
Dis done


显然,此时创建的4条线程可并发执行,同时处于working状态。一般情况下,初始化的信号量数目会小于创建的线程的数目,以此来达到同步器对线程并发的控制作用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: