zoukankan      html  css  js  c++  java
  • 信号量机制线程互斥

    Semaphore的使用

     

      Semaphore也是一个线程同步的辅助类,可以维护当前访问自身的线程个数,并提供了同步机制。使用Semaphore可以控制同时访问资源的线程个数,例如,实现一个文件允许的并发访问数。

    Semaphore的主要方法摘要:

      void acquire():从此信号量获取一个许可,在提供一个许可前一直将线程阻塞,否则线程被中断。

      void release():释放一个许可,将其返回给信号量。

      int availablePermits():返回此信号量中当前可用的许可数。

      boolean hasQueuedThreads():查询是否有线程正在等待获取

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    
    public class SemaphoreTest {
        public static void main(String[] args) {
            ExecutorService service = Executors.newCachedThreadPool();  //线程池
            final  Semaphore sp = new Semaphore(3);//创建Semaphore信号量,初始化许可大小为3
            for(int i=0;i<10;i++){   //创建10个线程
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e2) {
                    e2.printStackTrace();
                }
                Runnable runnable = new Runnable(){
                        public void run(){
                        try {
                            sp.acquire();//请求获得许可,如果有可获得的许可则继续往下执行,许可数减1。否则进入阻塞状态
                        } catch (InterruptedException e1) {
                            e1.printStackTrace();
                        }
                        System.out.println("线程" + Thread.currentThread().getName() +
                                "进入,当前已有" + (3-sp.availablePermits()) + "个并发");
                        try {
                            Thread.sleep((long)(Math.random()*10000));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("线程" + Thread.currentThread().getName() +
                                "即将离开");
                        sp.release();//释放许可,许可数加1
                        //下面代码有时候执行不准确,因为其没有和上面的代码合成原子单元
                        System.out.println("线程" + Thread.currentThread().getName() +
                                "已离开,当前已有" + (3-sp.availablePermits()) + "个并发");
                    }
                };
                service.execute(runnable);
            }
        }
    
    }

    单个信号量的Semaphore对象可以实现互斥锁的功能,并且可以是由一个线程获得了“锁”,再由另一个线程释放“锁”,这可应用于死锁恢复的一些场合。

    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Semaphore;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class LockTest {
        public static void main(String[] args) {
            final Business business = new Business();
            ExecutorService executor =  Executors.newFixedThreadPool(3);
            for(int i=0;i<3;i++)
            {
                executor.execute(
                        new Runnable()
                        {
                            public void run()
                            {
                                business.service();
                            }
                        }
    
                );
            }
            executor.shutdown();
        }
    
    private static class Business{
            private int count;
            Lock lock = new ReentrantLock();
            Semaphore sp = new Semaphore(1);
            public void service(){
                //lock.lock();
                try {
                    sp.acquire(); //当前线程使用count变量的时候将其锁住,不允许其他线程访问
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
                try {
                    count++;
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(count);
                }catch (RuntimeException e) {
                    e.printStackTrace();
                }
                finally
                {
                    //lock.unlock();
                    sp.release();  //释放锁
                }
            }
        }
    
    }
    没有停止的脚步,只有倒下去的脚步
  • 相关阅读:
    误删本地分支,两天的工作量差点毁于一旦,使用git reflog 有惊无险恢复
    单点登录SSO
    IdentityServer4介绍和使用
    常见的远程无线通信技术
    4G模块和DTU模块有何区别
    以太网IO控制器
    什么是无线网关,无线网关的功能
    什么是IOT网关,网关功能有哪些
    Modbus RTU和Modbus TCP的两种区别
    数据采集网关设备 如何选择数据采集网关
  • 原文地址:https://www.cnblogs.com/hkMblogs/p/13196924.html
Copyright © 2011-2022 走看看