并发场景&通用实现方案

并发代码设计公式

并发场景分类

场景1:一个线程负责执行任务,其他线程查询任务状态
场景2:多个线程有且仅有一个能执行任务
场景3:多个线程至少有一个能执行任务
场景4:一个线程处理其他线程提交的任务

并发代码设计

场景1

在这里插入图片描述

场景2请添加图片描述

场景3

在这里插入图片描述

场景4

在这里插入图片描述

  1. 生产者
public class TaskProducer extends Thread {

    public static AtomicInteger produceCount = new AtomicInteger(0);

    public static AtomicInteger produceSuccessCount = new AtomicInteger(0);

    private TaskConsumer consumer;
    private String data;

    public TaskProducer(TaskConsumer consumer, String data) {
        this.consumer = consumer;
        this.data = data;
    }

    @Override
    public void run() {
        produceCount.incrementAndGet();
        if (consumer.addData(data)) {
            produceSuccessCount.incrementAndGet();
        }

    }
}
  1. 消费者
public class TaskConsumer extends Thread {


    public static final int SLEEP = 0;
    public static final int AWAKE = 1;

    public static final int STOP = 0;
    public static final int START = 1;

    private List<String> dataList = new ArrayList<>();


    private AtomicInteger state = new AtomicInteger(AWAKE);

    private AtomicInteger enabled = new AtomicInteger(START);


    @Override
    public void run() {
        int dealCount = 0;
        while (true) {
            state.set(SLEEP);
            if (enabled.get() == START && dataList.isEmpty()) {
                LockSupport.park();
            }
            state.lazySet(AWAKE);
            if (Thread.currentThread().isInterrupted() || enabled.get() == STOP) {
                enabled.set(STOP);
                synchronized (this) {
                    System.out.println("已经处理的数据数量:" + dealCount);
                    System.out.println("取消处理的数据数量:" + dataList.size());
                    dataList.clear();
                }
                break;
            }
            if (!dataList.isEmpty()) {
                synchronized (this) {
                    dataList.remove(0);
                    dealCount++;
                }
            }
        }
    }

    public boolean addData(String data) {
        boolean result = true;
        if (enabled.get() == START) {
            synchronized (this) {
                dataList.add(data);
            }
            if (enabled.get() == STOP) {
                synchronized (this) {
                    if (dataList.remove(data))
                        return false;
                    else
                        return true;
                }
            }
        } else {
            return false;
        }
        if (result) {
            if (state.getAndSet(AWAKE) == SLEEP) {
                LockSupport.unpark(this);
            }
        }
        return result;
    }

    public void stopConsume() {
        enabled.set(STOP);
        if (state.getAndSet(AWAKE) == SLEEP) {
            LockSupport.unpark(this);
        }
    }

    public void interuptConsume() {
        this.interrupt();
    }


}
  1. 中断
    public void interuptConsume() {
        this.interrupt();
    }
  1. 停止消费
    public void stopConsume() {
        enabled.set(STOP);
        if (state.getAndSet(AWAKE) == SLEEP) {
            LockSupport.unpark(this);
        }
    }
  1. 测试代码
public class ConcurrentTest {

    /**
     * 生产消费同步
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        TaskConsumer consumer=new TaskConsumer();
        consumer.start();

        for(int i=0;i<1000000;i++){
            new TaskProducer(consumer,i+"").start();
        }
        consumer.stopConsume();
        Thread.sleep(1000);
        System.out.println("生产总数:"+ TaskProducer.produceCount.get()+",成功加入消费总数:"+ TaskProducer.produceSuccessCount);
    }
}

操作说明

等待队列

  1. 如果是队列仅有一个元素,则cas设置这个元素成功就算成功
  2. 如果队列中有多个元素,则需要cas队列头成功才算成功
  3. 如果是一个Map或者Set,就需要用锁来保证原子性

等待函数

  1. LockSupport的park函数与unpark函数
  2. Selector的select函数与wakeup函数
  3. CountDownLatch的await函数与countDown函数
  4. Object的wait函数与notify函数
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值