Using Semaphore to achieve multi-producer / multi-consumer mode --- I used the flexible bill in the project

The actual scenario for using this function is: our company has a module to generate simulated bills. There are two scenarios for simulated bills. When a certain bill is generated, the generation time is> 15 seconds. Call the send mail function to send mail when less than, we will download this simulated bill directly under the current browser.

Code

package com.zcw.demo2;

import java.util.concurrent.Semaphore;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @ClassName : RepastService
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-04-14 16:24
 */
public class RepastService {

    volatile private Semaphore setSemaphore = new Semaphore(10);//大于15秒的账单
    volatile private Semaphore getSetSemaphore = new Semaphore(20);//邮件组件
    volatile private ReentrantLock lock = new ReentrantLock();
    volatile private Condition setCondition = lock.newCondition();
    volatile private Condition getSetCondition = lock.newCondition();
    //producePosition变量含有是最多只有4个信道进行存储用户邮件地址
    volatile private Object[] producePosition = new Object[4];

    private boolean isEmpty() {
        boolean isEmpty = true;
        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] != null) {
                isEmpty = false;
                break;
            }
        }
        if (isEmpty == true) {
            return true;
        } else {
            return false;
        }
    }

    private boolean isFull() {
        boolean isFull = true;
        for (int i = 0; i < producePosition.length; i++) {
            if (producePosition[i] == null) {
                isFull = false;
                break;
            }
        }
        return isFull;
    }

    public void set() {
        try {
            //允许同时最多有10个邮箱账号进行发送
            setSemaphore.acquire();
            lock.lock();
            while (isFull()) {
                setCondition.await();
            }
            for (int i = 0; i < producePosition.length; i++) {
                if (producePosition[i] == null) {
                    producePosition[i] = "账单";
                    System.out.print(Thread.currentThread().getName() + "生成了" + producePosition[i]);
                    break;
                }
            }
            getSetCondition.signalAll();
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            setSemaphore.release();
        }
    }

    public void get() {
        try {
            getSetSemaphore.acquire();//允许同时最多有16个邮件发送
            lock.lock();
            while (isEmpty()) {
                //消费者等待
                getSetCondition.await();
            }
            for (int i = 0; i < producePosition.length; i++) {
                if (producePosition[i] != null) {
                    System.out.println(Thread.currentThread().getName() + "发送了" + producePosition[i]);
                producePosition[i]=null;
                break;
                }
            }
            setCondition.signalAll();
            lock.unlock();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            getSetSemaphore.release();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        RepastService repastService = new RepastService();
        ThreadP[] arrayP = new ThreadP[60];
        ThreadC[] arrayC = new ThreadC[60];
        for(int i =0;i<60;i++){
            arrayP[i] = new ThreadP(repastService);
            arrayC[i] = new ThreadC(repastService);
        }
        Thread.sleep(2000);
        for(int i=0;i<60;i++){
            arrayP[i].start();
            arrayC[i].start();
        }
    }
}

package com.zcw.demo2;

/**
 * @ClassName : ThreadC
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-04-14 16:57
 */
public class ThreadC extends Thread {
    private RepastService repastService;
    public ThreadC(RepastService repastService){
        super();
        this.repastService = repastService;
    }
    @Override
    public void run(){
        repastService.get();
    }
}

package com.zcw.demo2;

/**
 * @ClassName : ThreadP
 * @Description :
 * @Author : Zhaocunwei
 * @Date: 2020-04-14 16:55
 */
public class ThreadP extends Thread {
    private RepastService service;
    public ThreadP(RepastService repastService){
        super();
        this.service = repastService;
    }
    @Override
    public void run(){
        service.set();
    }
}

operation result:
Insert picture description here

Published 475 original articles · Like 16 · Visits 30,000+

Guess you like

Origin blog.csdn.net/qq_32370913/article/details/105576965