Semaphore类和Exchanger

Semaphore类

  1. 作用:限制线程并发的数量。
  2. 常用API
    1-1:semaphore(int permits)创建一个Semaphore与给定数量的许可证
    1-2:acquire(int permits)或者acquire() 获取一个或者permits个许可

1-3:release(int premits)或release()释放一个或者permits个许可,也可以动态增加permits个数
例子:
线程执行类:

package com.cjy;

import java.util.concurrent.Semaphore;

public class Service implements Runnable {
    //定义semaphore;指定同时并发量有两个,(发布两个许可)
 private Semaphore semaphore=new Semaphore(2);

    @Override
    public void run() {
        try {
            //使用其中一个许可
            semaphore.acquire(1);
            System.out.println(Thread.currentThread().getName()+"begin");
            Thread.sleep(5000);
            System.out.println(Thread.currentThread().getName()+"end");
            //释放其中一个许可;
            semaphore.release(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

Main类

package com.cjy;

public class Main {


    public static  void main(String[] args) throws InterruptedException {
     Service service=new Service();
    Thread   t1= new Thread(service);
     t1.setName("t1");
     t1.start();
    Thread t2 =   new Thread(service);
   t2 .setName("t2");
   t2 .start();
   Thread   t3  = new Thread(service);
  t3.setName("t3");
   t3.start();

    }


}

运行结果:
Semaphore类和Exchanger_第1张图片

1-4:semaphore.availablePermits() 获得当前可用的许可数
1-5:acquire是可以被中断的,而acquireUninterruptibly()方法是 “在等待许可的情况下不允许中断”。
1-6:drainPermits() 可获得并返回立刻可用的所有许可个数,并将可用许可置为0
1-7:getQueueLength() 获取等待许可的线程个数
1-8:hasQueuedThreads() 判断是否有没有线程在等待许可

  1. 公平与非公平信号量的
    4.1:公平信号量是:获得锁的顺序与线程启动的顺序有关。(先启动的线程先获得许可;只能在概率上保证有关)
    4.2: 非公平信号量:线程启动的顺序与调用semaphore.acquire()顺序无关
    4.3:semaphore构造方法中:
    Semaphore类和Exchanger_第2张图片

5.非阻塞获取许可

方法:
	A: tryAcquire()或 tryAquire(long timeOut,TimeUnit timeUnit)
		尝试的获取许可(1个),若获取不到则返回false。(带timeOut是在指定回见内尝试地获取锁)
	B:tryAcquire(int permit)或 tryAcquire(int permit,long timeOut,TimeUnit timeUnit)
		尝试的获取许可(permit个),若获取不到则返回false。(带timeOut是在指定回见内尝试地获取锁)
用法:用if语句,若获取不到,则继续走else语句,保证线程不会阻塞在那里。

Exchanger类

  1. Exchanger是线程间交换信息的方法之一

  2. 通过exchange()方法向两个格子填充信息;

     2-1:当两个格子中的均被填充时,该对象会自动将两个格子的信息交换,然后返回给线程,从而实现两个线程的信息交换
     2-2:若没有其他线程取得数据,则一直阻塞等待。
    
  3. API

     3-1:exchange(String v):  像格子里面添加数据。
     3-2:exchange(String v,long timeOut,TimeUnit timeunit):  像格子里面添加数据,若在timeout个单位时间内,没有其他线程取出,就会抛出TimeOutException异常
    

小节

  1. Semaphore类是用于控制线程并发个数的解决方法,通过许可数量进行操控
  2. Exchanger是线程间传输数据的方法之一;比喻为两个格子,线程利用exchange()方法向里面传送数据,若两个格子都有数据,则互换数据。若没有则无限阻塞等待或者有限时间内阻塞等待。

你可能感兴趣的:(JAVA多线程深入)