加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java开发中的Mutex vs Semaphore

发布时间:2020-12-14 06:22:41 所属栏目:Java 来源:网络整理
导读:先看一下stackoverflow上是怎么说的吧 原文地址:http://stackoverflow.com/questions/771347/what-is-mutex-and-semaphore-in-java-what-is-the-main-difference mutex can only count to 1 Suppose you have a thread running which accepts client connec

先看一下stackoverflow上是怎么说的吧

原文地址:http://stackoverflow.com/questions/771347/what-is-mutex-and-semaphore-in-java-what-is-the-main-difference

mutex can only count to 1  Suppose you have a thread running which accepts client connections. This thread can handle 10 clients simultaneously. Then each <span style="color: #0000ff;">new client sets the semaphore until it reaches 10.When the Semaphore has 10 flags,then your thread won't accept new connections
<span style="color: #000000;">
  Mutex are usually used
<span style="color: #0000ff;">for guarding stuff. Suppose your 10 clients can access multiple parts of the system. Then you can protect a part of the system with a mutex so when 1 client is connected to that sub-system,no one <span style="color: #0000ff;">else should have access. You can use a Semaphore <span style="color: #0000ff;">for <span style="color: #0000ff;">this purpose too. A mutex is a "Mutual Exclusion Semaphore".

简单的说 就是Mutex是排它的,只有一个可以获取到资源,?Semaphore也具有排它性,但可以定义多个可以获取的资源的对象。

1.Semaphore

Semaphore维护了一组许可令牌,使用acquire方法去获取许可令牌,而使用release方法去释放一个令牌。实际上没有真正的使用许可令牌,Semaphore仅仅维护了可用的计数器而已。

Semaphore通常用来限制可用访问一些(物理或者逻辑)资源的访问线程数。例如,下面的类使用Semaphore来控制对pool内item的访问量。

示例:

MAX_AVAILABLE = 100 Semaphore available = Semaphore(MAX_AVAILABLE,<span style="color: #0000ff;">public Object getItem() <span style="color: #0000ff;">throws<span style="color: #000000;"> InterruptedException {
available.acquire();
<span style="color: #0000ff;">return
<span style="color: #000000;"> getNextAvailableItem();
}

<span style="color: #0000ff;">public <span style="color: #0000ff;">void<span style="color: #000000;"> putItem(Object x) {
<span style="color: #0000ff;">if<span style="color: #000000;"> (markAsUnused(x))
available.release();
}

<span style="color: #008000;">//<span style="color: #008000;"> Not a particularly efficient data structure; just for demo

<span style="color: #0000ff;">protected Object[] items =<span style="color: #000000;"> ... whatever kinds of items being managed
<span style="color: #0000ff;">protected <span style="color: #0000ff;">boolean[] used = <span style="color: #0000ff;">new <span style="color: #0000ff;">boolean<span style="color: #000000;">[MAX_AVAILABLE];

<span style="color: #0000ff;">protected <span style="color: #0000ff;">synchronized<span style="color: #000000;"> Object getNextAvailableItem() {
<span style="color: #0000ff;">for (<span style="color: #0000ff;">int i = 0; i < MAX_AVAILABLE; ++<span style="color: #000000;">i) {
<span style="color: #0000ff;">if (!<span style="color: #000000;">used[i]) {
used[i] = <span style="color: #0000ff;">true<span style="color: #000000;">;
<span style="color: #0000ff;">return<span style="color: #000000;"> items[i];
}
}
<span style="color: #0000ff;">return <span style="color: #0000ff;">null; <span style="color: #008000;">//<span style="color: #008000;"> not reached
<span style="color: #000000;"> }

<span style="color: #0000ff;">protected <span style="color: #0000ff;">synchronized <span style="color: #0000ff;">boolean<span style="color: #000000;"> markAsUnused(Object item) {
<span style="color: #0000ff;">for (<span style="color: #0000ff;">int i = 0; i < MAX_AVAILABLE; ++<span style="color: #000000;">i) {
<span style="color: #0000ff;">if (item ==<span style="color: #000000;"> items[i]) {
<span style="color: #0000ff;">if<span style="color: #000000;"> (used[i]) {
used[i] = <span style="color: #0000ff;">false<span style="color: #000000;">;
<span style="color: #0000ff;">return <span style="color: #0000ff;">true<span style="color: #000000;">;
} <span style="color: #0000ff;">else
<span style="color: #0000ff;">return <span style="color: #0000ff;">false<span style="color: #000000;">;
}
}
<span style="color: #0000ff;">return <span style="color: #0000ff;">false<span style="color: #000000;">;
}

}

在访问池内的item时,每个线程必须从Semaphore来获取一个许可令牌,保证必须有一个item是可用的。当线程使用完item后,将item还回到pool中,此时访问令牌返回给Semaphore。

注意:当调用acquire方法是没有保持一个同步锁,因为同步锁会阻碍item被释放给pool。Semaphore封装了需要的同步操作来保证对pool的访问进行限制,而不是为了维持pool本身的一致性来加入同步操作。

Semaphore默认设置为1,用来保证至少有一个许可令牌可用,此时可用看做一个mutext排它锁。mutex因作为二分Semaphore而出名,要么有一个许可令牌,要么没有许可令牌。当这样使用时,二分Semaphore有熟悉(不像大部分lock的实现那样),lock由线程释放而非owner(Semaphore没有ownership的概念)。这在某些特殊的场景下很有用,比如死锁的恢复。

Semaphore类的构造方法可以接受一个fairness参数,当这个参数设置为false时,此类不保证线程获取到许可令牌的顺序,特别是当运行抢夺资源时,意味着一个线程使用acquire获取许可令牌的时间可能会比一个等待队列在它之前的线程获取到令牌更早--逻辑上来说,新线程放置月等待队列的头部。当fairness参数设置为true时,Semaphore保证线程调用acquire方法时的顺序获取到令牌(即先进先出FIFO)

参考文献:

【1】http://www.cnblogs.com/think-in-java/p/5520462.html

【2】http://blog.csdn.net/sunp823/article/details/49886051

【3】http://coolxing.iteye.com/blog/1236909

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读