Semaphore的使用

江枫思渺然 提交于 2019-12-04 02:28:15

1. Semaphore介绍:

Semaphore (信号量)从概念上讲维护了一个许可集. 在获取acquire()到许可之后才能执行任务,每获取一次许可,许可数-1,在线程释放release()之后许可数+1。Semaphore就是根据许可数来控制线程并发执行的。为了更加形象说明Semaphore作用,这里举一个例子如下:


2. Semaphore的简单用法:

Run.java

package com.test.semaphore;

/**
 * Created by famiover on 16/9/26.
 */
public class Run {
    public static void main(String[] args) {
        Service service = new Service();
        for (int i = 0; i < 100; i++) {
            MyThread myThread = new MyThread(service);
            myThread.setName("Thread" + i);
            myThread.start();
        }
    }
}

Mythread.java

package com.test.semaphore;


/**
 * Created by famiover on 16/9/26.
 */
public class MyThread extends Thread {
    private Service service;
    public MyThread(Service service){
        this.service=service;
    }
    @Override
    public void run(){
      service.doSomething();
    }
}

Service.java

package com.test.semaphore;


/**
 * Created by famiover on 16/9/26.
 */
public class Service {
    public static int count=0;
    public void doSomething(){
        System.out.println(Thread.currentThread().getName()+"得到的count:"+getCount());
        setCount();
    }
    public int getCount(){
        return count;
    }
    public void setCount(){
        count++;
    }
}

结果如下:

运行结果

从结果可以看出多线程并发方法造成数据并非递增的现象。这里可以使用Semaphore 改造一下*** Service.java ***就可以得到期望的结果:

package com.test.semaphore;

import java.util.concurrent.Semaphore;

/**
 * Created by famiover on 16/9/26.
 */
public class Service {
    private Semaphore semaphore=new Semaphore(1);
    public static int count=0;
    public void doSomething(){
        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+"得到的count:"+getCount());
        setCount();

        semaphore.release();
    }
    public int getCount(){
        return count;
    }
    public void setCount(){
        count++;
    }
}

3.Semaphore的常用方法:

方法 作用
acquire 从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。
tryAcquire 从信号量尝试获取一个许可,如果无可用许可,直接返回false,不会阻塞。
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!