首页 > 其他 > 详细

exchanger 和semaphore

时间:2019-05-07 17:03:41      阅读:128      评论:0      收藏:0      [点我收藏+]

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

 

exchanger 和semaphore

原文:https://www.cnblogs.com/bj-xiaodao/p/10821080.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!