1.阻塞式队列
生产者消费者模型
生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而 通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者 要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队 列就是用来给生产者和消费者解耦的
import java.util.Random;
public class MessageQueue {
private int[] items;
private int putIndex;
private int takeIndex;
private volatile int size;
public MessageQueue(int capacity) {
items = new int[capacity];
putIndex = 0;
takeIndex = 0;
size = 0;
}
public void put(int message) throws InterruptedException {
do {
synchronized (this) {
if (size < items.length) {
items[putIndex] = message;
putIndex = (putIndex + 1) % items.length;
size++;
notifyAll();
return;
}
}
while (size == items.length) {
synchronized (this) {
if (size == items.length) {
wait();
}
}
}
} while (true);
}
public int take() throws InterruptedException {
do {
synchronized (this) {
if (size > 0) {
int message = items[takeIndex];
takeIndex = (takeIndex + 1) % items.length;
size--;
notifyAll();
return message;
}
}
while (size == 0) {
synchronized (this) {
if (size == 0) {
wait();
}
}
}
} while (true);
}
public synchronized int size() {
return size;
}
public static void main(String[] args) {
MessageQueue queue = new MessageQueue();
Thread producer = new Thread(() -> {
Random random = new Random();
for (int i = 0; i < 100_0000_0000; i++) {
queue.put(random.nextInt(100000);
}
}, "生产者"); Thread customer = new Thread(() -> {
while (true) {
int message = queue.take();
System.out.println(message);
}
}, "消费者");
}
}
2.定时器
import java.util.concurrent.PriorityBlockingQueue;
public class Timer {
private static class TimerTask implements Comparable<TimerTask> {
private Runnable command;
private long time;
private TimerTask(Runnable command, long after) {
this.command = command;
this.time = System.currentTimeMillis() + after;
}
private void run() {
command.run();
}
@Override
public int compareTo(TimerTask o) {
return (int) (time - o.time);
}
}
private PriorityBlockingQueue<TimerTask> queue = new PriorityBlockingQueue<>();
private Object mailbox = new Object();
private class Worker extends Thread {
@Override
public void run() {
while (true) {
try {
TimerTask task = queue.take();
long ms = System.currentTimeMillis();
if (task.time > ms) {
queue.put(task);
synchronized (mailbox) {
mailbox.wait(task.time - ms);
}
} else {
task.run();
}
} catch (InterruptedException e) {
break;
}
}
}
}
public Timer() {
Worker worker = new Worker();
worker.start();
}
public void schedule(Runnable command, long after) {
TimerTask task = new TimerTask(command, after);
queue.offer(task);
synchronized (mailbox) {
mailbox.notify();
}
}
public static void main(String[] args) throws InterruptedException {
Timer timer = new Timer();
Runnable command = new Runnable() {
@Override
public void run() {
System.out.println("我来了");
timer.schedule(this, 3 * 1000);
}
};
timer.schedule(command, 3 * 1000);
}
}
3.线程池
线程池最大的好处就是减少每次启动、销毁线程的损耗
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ThreadPool {
private static class Worker extends Thread {
}
private BlockingQueue<Runnable> jobQueue;
private int nCurrentThreads;
private int nThreads;
private Worker[] workers;
public ThreadPool(int nThreads, int nCachedJobs) {
this.jobQueue = new ArrayBlockingQueue<>(nCachedJobs);
this.nCurrentThreads = 0;
this.nThreads = nThreads;
this.workers = new Worker[nThreads];
}
public void execute(Runnable command) throws InterruptedException {
if (nCurrentThreads < nThreads) {
Worker worker = new Worker();
workers[nCurrentThreads++] = worker;
worker.start();
} else {
jobQueue.put(command);
}
}
}