并发代码设计公式
并发场景分类
场景1:一个线程负责执行任务,其他线程查询任务状态
场景2:多个线程有且仅有一个能执行任务
场景3:多个线程至少有一个能执行任务
场景4:一个线程处理其他线程提交的任务
并发代码设计
场景1
场景2![请添加图片描述](https://img-blog.csdnimg.cn/direct/70fe83a328c6444fab85fb27e6ee445a.jpeg)
场景3
场景4
- 生产者
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();
}
}
}
- 消费者
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();
}
}
- 中断
public void interuptConsume() {
this.interrupt();
}
- 停止消费
public void stopConsume() {
enabled.set(STOP);
if (state.getAndSet(AWAKE) == SLEEP) {
LockSupport.unpark(this);
}
}
- 测试代码
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);
}
}
操作说明
等待队列
- 如果是队列仅有一个元素,则cas设置这个元素成功就算成功
- 如果队列中有多个元素,则需要cas队列头成功才算成功
- 如果是一个Map或者Set,就需要用锁来保证原子性
等待函数
- LockSupport的park函数与unpark函数
- Selector的select函数与wakeup函数
- CountDownLatch的await函数与countDown函数
- Object的wait函数与notify函数