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

 

转载于:https://www.cnblogs.com/bj-xiaodao/p/10821080.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值