首页 > 技术文章 > java 信号量简单分析

xxss0903 2016-11-01 11:09 原文

1. 先看几个semaphore的写法,可以看到semaphore的acquire和release都是和wait和notify相关的

// 设置最大信号量
public class SemaphoreMax {
    private int signals = 0;
    private int bound = 0;
    public SemaphoreMax(int bound){
        this.bound = bound;
    }
    
    public synchronized void take() throws InterruptedException{
    
        // 信号量达到最大,那么就进入等待,后面的那个回去执行,
        // 然后等待执行完成再去释放信号量,然后去唤醒,唤醒之后又有新的线程进入
        // ,就会使得信号量增加,然后又进入等待
        while(this.signals == bound){
            wait();
        }
        this.signals ++;
        this.notify();
    }
    
    public synchronized void release() throws InterruptedException{
        while(this.signals == 0){
            wait();
        }
        this.signals --;
        this.notify();
    }
}

在上面的简单semaphore例子中,有一个最大的信号量,有一个统计当前信号量的signal

从take方法中对应java中的acquire方法,表示获取一个信号量,当我们获取到一个信号量之后,先判断当前是否信号量已经被使用完毕了,如果使用完了,那么就让所有线程进行等待,如果没有到达最大信号量,,那么就唤醒一个线程进行操作。

在release方法中对应java中的release方法,表示释放一个信号量,当调用这个方法之后会去判断当前的信号量是否为0,也就是是否有可用的信号量,如果有可用的信号量,那么就会在下面减去一个可用的信号量,然后唤醒一个线程,这样在下次我们take获取的时候就会有一个线程能够进入take方法然后去判断当前对象所持有的信号量是否达到最大。

2. 看一个用信号量控制绘图的示例:

上面是对两个量进行比较,然后并且有一个标志来判断当前的排序比较是否继续进行,如果run为false,也就是点击了暂停,那么就获取一个信号量,让当前线程进入等待状态,因为信号量只有一个信号。

当点击继续运行的时候就释放一个信号量,然后设置run为false,并且释放一个信号量,然后这个信号量就会在下面的比较中进行一次,然后再次acquire一个信号量,然后这个信号量执行完了之后因为已经达到了最大的信号量,所以当前线程就会处于wait状态,这样绘制就会暂停,然后通过再次点击这个上面的方法设置run为false,并且release一个信号量,这样线程继续运行到判断run的比较上面。

 

推荐阅读