Semaphore控制并发

Semaphore类是控制并发的数量的并发类,主要作用就是限制线程并发的数量,如果不限制线程并发的数量,cpu的资源很快就耗尽了,每个线程访问的效率也会比较低下,因为cpu要把时间片分配给不同的线程对象,而且上下文切换也要耗时,所以限制线程数量非常重要。

比如说一个生产商,发布了10个代理销售许可,所以最多只有10个代理商来获取其中的一个许可,限制到申请数量,这也就是Semaphore要达到的目的。

使用场景一:实现线程互斥同步,同一时间就一个线程对一个方法进行访问。

package cn.wzy.maintest;
  
import java.util.Date;
import java.util.concurrent.Semaphore;
  
public class SemaphoreTest {
  
  
    private Semaphore semaphore = new Semaphore(1);
  
  
    public void method() {
        try {
            semaphore.acquire(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
  
  
        System.out.println(Thread.currentThread().getName() + "," + new Date().getTime());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
          
        semaphore.release(1);
    }
}

说明:new Semaphore(n)的构造参数代表生成n个许可证,acquire(m)代表访问一次需要m许可证,release(k)代表释放k个许可证,上面的代码指的是发布1个许可,然后每次访问需要1个许可,那就代表同一时间只会有一个线程访问method方法。

测试及结果:新建10个线程,输出线程执行情况。

package cn.wzy.maintest;
  
public class Main {
    public static void main(String[] args) {
  
        SemaphoreTest service = new SemaphoreTest();
        Thread[] threads = new Thread[10];
        for (int i = 0; i < 10; i++) {
            threads[i] = new Thread(()->
                service.method()
            );
            threads[i].setName("thread:" + i);
            threads[i].start();
        }
        while (Thread.activeCount() > 2) {
            Thread.yield();
        }
    }
}
thread:0,1528684590813
thread:1,1528684591813
thread:2,1528684592813
thread:3,1528684593813
thread:4,1528684594813
thread:5,1528684595814
thread:6,1528684596814
thread:7,1528684597814
thread:8,1528684598814
thread:9,1528684599815
  
Process finished with exit code 0

结果显示同一时间只有一个线程访问method。

使用场景二:控制线程访问的数量,此时线程不会实现互斥同步,只是减少线程的访问数量,线程之间还是会有线程安全问题。

package cn.wzy.maintest;
  
import java.util.Date;
import java.util.concurrent.Semaphore;
  
public class SemaphoreTest {
  
  
    private Semaphore semaphore = new Semaphore(10);
  
  
    public void method() {
        try {
            semaphore.acquire(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
  
  
        System.out.println(Thread.currentThread().getName() + "," + new Date().getTime());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
  
        semaphore.release(2);
    }
}
thread:1,1528684955678
thread:0,1528684955679
thread:2,1528684955679
thread:3,1528684955679
thread:4,1528684955679
thread:5,1528684956678
thread:6,1528684956679
thread:7,1528684956679
thread:8,1528684956679
thread:9,1528684956679
  
Process finished with exit code 0
结果说明:最开始只是有10个许可证,然而每次访问需要2个许可证,也就是说同一时间最多只有5个线程同时访问。

猜你喜欢

转载自blog.csdn.net/qq_38089964/article/details/80803299