Android之Semaphore使用

Posted LVXIANGAN

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android之Semaphore使用相关的知识,希望对你有一定的参考价值。

Semaphore(信号量),是一种共享锁,多个线程同时访问一个资源时,通过它实现同一时刻的访问线程数量。位于java.util.concurrent.Semaphore,最常见的使用场景就是高并发下的限流。

举个例子:有10000辆车同时要涌入高速公路,但高速入口没有ETC只有2条人工发卡车道,所有人都必须要被收费亭许可(收费亭确认放行)后才能进入高速。高速公路是大家要共同使用的资源,收费亭就是Semaphore,2个发卡通道是Semaphore的同时允许车辆通过的许可证数量

使用代码示例:



public class TestCar 
​
    //收费站同时容纳的车辆2
    private  static  Semaphore semaphore=new Semaphore(2);
​
    public static void main(String[] args) 
​
        //模拟100辆车进入停车场
        for(int i=0; i<10000; i++)
​
            Thread thread=new Thread(new Runnable() 
                public void run() 
                    try 
                        System.out.println("===="+Thread.currentThread().getName()+"来到收费站");
                        if(semaphore.availablePermits()==0) 
                            System.out.println("工作人员正为其他车辆发卡,请耐心等待");
                        
                        semaphore.acquire();//获取令牌尝试进入收费亭
                        System.out.println(Thread.currentThread().getName()+"成功进入收费亭");
                        //.....
                        //模拟车辆在收费亭停留时间
                        System.out.println(Thread.currentThread().getName()+"驶入高速公路");
                        semaphore.release();//释放令牌,腾出车位,处理下一台车
                     catch (InterruptedException e) 
                        e.printStackTrace();
                    
                
            , i + "号车");
​
            thread.start();

        
    

其他用法:利用new Semaphore(0) 进行初始化控制,初始化完成后通过Semaphore.release释放锁,继续执行其他代码。以场景说明:外卖快递员收到推送过来的订单,进行订单信息梳理确认,开始派送订单到客户手上

public class MainActivity extends AppCompatActivity 

    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 收到订单
        String orderData = "你收到新的外卖订单,订单详情....";
        // 处理订单
        Postman.getInstance().onReceiveOrder(orderData);
    



/**
 * 注意:实现了Runnable接口
 */
public class Postman implements Runnable 
    private static Postman mInstance;
    private Semaphore semaphore = new Semaphore(0);

    // 初始化
    public static Postman getInstance() 
        if (null == mInstance) 
            synchronized (Postman.class) 
                if (null == mInstance) 
                    mInstance = new Postman();
                
            
        
        return mInstance;
    

    public void onReceiveOrder(String data) 
        System.out.println("处理订单数据,确认收货人姓名、地址等,代码略……");
        // 这句代码,会释放锁进入run()方法,触发开始派送流程
        semaphore.release();
    

    // 开启一个后台线程,执行派送订单操作
    public Postman() 
        new Thread(this).start();
    

    @Override
    public void run() 
        // 循环检查订单,如果有订单进行派送
        while (true) 
            if (semaphore.tryAcquire())  // 因为许可证数量是0,这里会一直阻塞,直到释放锁(semaphore.release) 才会执行下面代码
                System.out.println("收到订单,开始派送,代码自行扩展....");
             else 
                try 
                    Thread.sleep(1000);
                 catch (Exception ex) 
                    ex.printStackTrace();
                
            
        
    

从上面代码可以看出:在订单处理没有完成之前,semaphore会一直等待release通知,阻塞派单流程的代码,知道release释放锁后,才会往下执行。

以上是关于Android之Semaphore使用的主要内容,如果未能解决你的问题,请参考以下文章

Android之Semaphore使用

Android之Semaphore使用

Java并发多线程编程——Semaphore

Android中的Semaphore

死磕 java同步系列之Semaphore源码解析

死磕 java同步系列之Semaphore源码解析