• exchanger 和semaphore


    exchanger

    1.它的使用必须是成对出现的.如果不是成对的话,可能交换错误

    2.exchanger 交换的信息是同一个内存地址,而不是copy 会涉及到线程安全的问题

      /**
         * exchange 是成对出现的,如果在有一个线程是A1的话 有可能是交换错误了.
         *如果超时了.,另一个会不会结束
         * @param args
         */
        public static void main(String[] args) {
            Exchanger<String> exchanger = new Exchanger<>();
    
            new  Thread(()->{
    
                try {
                    System.out.println(Thread.currentThread().getName()+"  start" );
                    String exchange = exchanger.exchange("i am come from thread a ",10, TimeUnit.SECONDS);
                    System.out.println(Thread.currentThread().getName()+"  接受 value = "+ exchange);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                    System.out.println("超时...");
                }
                System.out.println(Thread.currentThread().getName()+"  end " );
    
            },"A").start();
            new  Thread(()->{
    
                try {
                    System.out.println(Thread.currentThread().getName()+"  start" );
                    String exchange = exchanger.exchange("i am come from thread a ",10, TimeUnit.SECONDS);
                    System.out.println(Thread.currentThread().getName()+"  接受 value = "+ exchange);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (TimeoutException e) {
                    e.printStackTrace();
                    System.out.println("超时...");
                }
                System.out.println(Thread.currentThread().getName()+"  end " );
    
            },"A1").start();
    
            new  Thread(()->{
    
                try {
                    System.out.println(Thread.currentThread().getName()+"  start" );
    //                TimeUnit.SECONDS.sleep(13);
                    String exchange = exchanger.exchange("i am come from thread b ");
                    System.out.println(Thread.currentThread().getName()+" 接受  value = "+ exchange);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"  end " );
    
            },"B").start();
    
        }

    3.exchanger 是可以一直发生交换的

     public static void main(String[] args) {
            Exchanger<Integer> exchanger = new Exchanger<>();
    
            new  Thread(()->{
    
                try {
                    AtomicReference<Integer> atomicReference = new AtomicReference<>(1);
                    while (true){
                        TimeUnit.SECONDS.sleep(2);
                        Integer exchange = exchanger.exchange(atomicReference.get());
                        System.out.println(Thread.currentThread().getName()+"  接受 value = "+ exchange);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
            },"thread-A").start();
            new  Thread(()->{
    
                try {
                    AtomicReference<Integer> atomicReference = new AtomicReference<>(2);
                    while (true){
                        TimeUnit.SECONDS.sleep(1);
                        Integer exchange = exchanger.exchange(atomicReference.get());
                        System.out.println(Thread.currentThread().getName()+"  接受 value = "+ exchange);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
            },"thread-B").start();
    
        }
    View Code

     semaphore

    调用semaphore的话,你可以定义许可证,就是同一个时间.只能这么多线程来访问.

     Semaphore semaphore = new Semaphore(2);

       public static void main(String[] args) {
    
            Semaphore semaphore = new Semaphore(2);
    
            for (int i = 0; i <2 ; i++) {
                new Thread(()->{
                    System.out.println(Thread.currentThread().getName()+"in");
                    try {
                        semaphore.acquire();
                        System.out.println(Thread.currentThread().getName()+"   get the semaphore");
                        TimeUnit.SECONDS.sleep(5);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    semaphore.release();
                    System.out.println(Thread.currentThread().getName()+"out");
                }).start();
    
            }
        }

    如果是一个那么同一时间只能一个.线程

    那么他的作用在哪里呢?

    我们可以想象,数据库连接池.假设我们有10个连接.但是现在同一个时间来了20个请求.那么就需要等到前面10个连接结束之后就可以连接了.起到了限流作用.

    一些策略

    1.就是等待阻塞着 .

    2.直接中断

    3.定时放弃

    4.直接获取结果

    API的使用

    semaphore.availablePermits() 可用的许可证 

    semaphore.acquireUninterruptibly(); 忽视中断.

     semaphore.acquire(2); 一次获取几个许可证

     semaphore.drainPermits(); 获取的所有的许可证 释放之后第二个线程才会执行

       public static void main(String[] args) throws InterruptedException {
    
            Semaphore semaphore = new Semaphore(5);
    
            Thread thread = new Thread(() -> {
                //获取到所有的额
                try {
                    semaphore.drainPermits();
                    System.out.println(Thread.currentThread().getName() + "  in");
                    TimeUnit.SECONDS.sleep(5);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release(5);
                }
            });
            thread.start();
    
            TimeUnit.MILLISECONDS.sleep(50);
            Thread t2 = new Thread(() -> {
    
                try {
                    System.out.println(Thread.currentThread().getName() + "  in");
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()+" out");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    semaphore.release();
                }
            });
        t2.start();
    
        }
    View Code

    semaphore.hasQueuedThreads() 是否有线程正在获取信号量

    boolean b = semaphore.tryAcquire(); 这个方法是尝试去获取.如果获取不到就算了.

    tryAcquier(1,timeUnit.SECONDS) 尝试使用多长时间来获取

      public static void main(String[] args) throws InterruptedException {
    
            Semaphore semaphore = new Semaphore(1);
    
            Thread thread = new Thread(() -> {
                //获取到所有的额
                try {
    
                    boolean b = semaphore.tryAcquire();
                    TimeUnit.SECONDS.sleep(2);
                    System.out.println(b);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
            });
            thread.start();
    
            TimeUnit.MILLISECONDS.sleep(50);
            Thread t2 = new Thread(() -> {
    
                try {
                    boolean b = semaphore.tryAcquire(1,TimeUnit.SECONDS);
                    if(b){
                        System.out.println(b);
                        System.out.println(Thread.currentThread().getName()+" 可以");
                    }else{
                        System.out.println(b);
                        System.out.println(Thread.currentThread().getName()+"不可以");
                    }
    
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    semaphore.release();
                }
            });
        t2.start();
    
        }
    View Code
  • 相关阅读:
    关于音视频同步
    redis JedisConnectionException: Could not get a resource from the pool
    ping指定IP的指定端口号
    如何查看端口号是否被占用
    mongodb增删改查基础语法
    mongodb重置密码
    本地MongoDB服务开启与连接本地以及远程服务器MongoDB服务
    MongoDB服务的安装与删除
    可视化
    Elasticsearch下载安装
  • 原文地址:https://www.cnblogs.com/bj-xiaodao/p/10821080.html
Copyright © 2020-2023  润新知