public class FooBar {
private int n;
//共享变量都用 volatile 省得有问题
private volatile boolean flag=false;
FooBar(int n){
this.n=n;
}
public void foo() throws InterruptedException {
int i=0;
//第一个循环是为了重复调用n次foo()
while (i{
try {
fooBar.foo();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(()->{
try {
fooBar.bar();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
按顺序指定唤醒使用ReentrantLock,注意:显示的加锁和释放锁
public class AbcdLock {
private int n;
private volatile int size=0;
private Lock lock = new ReentrantLock();
//按顺序指定唤醒使用ReentrantLock
private Condition aCondition = lock.newCondition();
private Condition bCondition = lock.newCondition();
private Condition cCondition = lock.newCondition();
private Condition dCondition = lock.newCondition();
public AbcdLock(int n) {
this.n = n;
}
public void addA() {
while (size<=4*n) {
lock.lock();
try {
if (size % 4 != 0) {
// 添加A的线程等待
aCondition.await();
}
size++;
System.out.println("A");
// 指定唤醒添加B的线程
bCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public void addB() {
while (size<=4*n) {
lock.lock();
try {
if (size % 4 != 1) {
// 添加A的线程等待
bCondition.await();
}
size++;
System.out.println("B");
// 指定唤醒添加B的线程
cCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public void addC() {
while (size<=4*n) {
lock.lock();
try {
if (size % 4 != 2) {
// 添加A的线程等待
cCondition.await();
}
size++;
System.out.println("C");
// 指定唤醒添加B的线程
dCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public void addD() {
while (size<=4*n) {
lock.lock();
try {
if (size % 4 != 3) {
// 添加A的线程等待
dCondition.await();
}
size++;
System.out.println("D");
// 指定唤醒添加B的线程
aCondition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
public static void main(String[] args) throws InterruptedException {
AbcdLock abcdLock = new AbcdLock( 10);
new Thread(() -> {
abcdLock.addA();
}).start();
new Thread(() -> {
abcdLock.addB();
}).start();
new Thread(() -> {
abcdLock.addC();
}).start();
new Thread(() -> {
abcdLock.addD();
}).start();
Thread.sleep(30);
}
}
核心思想:使用 ReentrantLock,加两个条件队列(isFUll,isEmpty)
注意:实现公共方法put和take没有先while循环,因为put,take每次只用一次,注意与上边区分
public class MyBlockingQueue {
private Deque queue;
private int capacity;
private Lock lock = new ReentrantLock();
private Condition isFull = lock.newCondition();
private Condition isEmpty = lock.newCondition();
public MyBlockingQueue(int capacity) {
this.queue = new LinkedList<>();
this.capacity = capacity;
}
public void put(String item) throws InterruptedException {
lock.lock();
try{
while (queue.size()>=capacity){
isFull.await();
}
queue.addLast(item);
isEmpty.signal();
}finally {
lock.unlock();
}
}
public String take() throws InterruptedException {
lock.lock();
String res = null;
try {
// 队列已满
while (queue.size() == 0) {
// take线程等待
isEmpty.await();
}
res = queue.pollFirst();
// 唤醒put线程
isFull.signalAll();
return res;
} finally {
lock.unlock();
}
}
public static void main(String[] args) {
MyBlockingQueue blockingQueue = new MyBlockingQueue(64);
new Thread(()-> {
for (int i = 0; i < 100; i++) {
try {
blockingQueue.put(String.valueOf(i));
System.out.println("放入" + i);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(()-> {
for (;;) {
try {
System.out.println("取出" + blockingQueue.take());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
用阻塞队列最为简单:
public class Producer extends Thread {
// 间隔时间
private int duration;
private BlockingQueue blockingQueue;
public Producer (int duration, BlockingQueue blockingQueue) {
this.duration = duration;
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (true) {
try {
// 队列满时,put操作将被阻塞直到队列有空间为止
blockingQueue.put("Producer_" + Thread.currentThread().getName());
Thread.sleep(1000 * duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
// 消费者
public class Consumer extends Thread {
// 间隔时间
private int duration;
private BlockingQueue blockingQueue;
public Consumer (int duration, BlockingQueue blockingQueue) {
this.duration = duration;
this.blockingQueue = blockingQueue;
}
@Override
public void run() {
while (true) {
try {
String e = blockingQueue.take();
Thread.sleep(1000 * duration);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class TestMain {
public static void main(String[] args) {
BlockingQueue resource = new ArrayBlockingQueue<>(24);
new Producer(3, resource).start();
new Producer(3, resource).start();
new Producer(3, resource).start();
new Consumer(1, resource).start();
new Consumer(1, resource).start();
}
}
2.syn。。。
/**
* 生产者消费者模式:使用Object.wait() / notify()方法实现
*/
public class ProducerConsumer {
private static final int CAPACITY = 5;
public static void main(String args[]){
Queue queue = new LinkedList();
Thread producer1 = new Producer("P-1", queue, CAPACITY);
Thread producer2 = new Producer("P-2", queue, CAPACITY);
Thread consumer1 = new Consumer("C1", queue, CAPACITY);
Thread consumer2 = new Consumer("C2", queue, CAPACITY);
Thread consumer3 = new Consumer("C3", queue, CAPACITY);
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
consumer3.start();
}
/**
* 生产者
*/
public static class Producer extends Thread{
private Queue queue;
String name;
int maxSize;
int i = 0;
public Producer(String name, Queue queue, int maxSize){
super(name);
this.name = name;
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run(){
while(true){
synchronized(queue){
while(queue.size() == maxSize){
try {
System.out .println("Queue is full, Producer[" + name + "] thread waiting for " + "consumer to take something from queue.");
queue.wait();
} catch (Exception ex) {
ex.printStackTrace();
}
}
System.out.println("[" + name + "] Producing value : +" + i);
queue.offer(i++);
queue.notifyAll();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 消费者
*/
public static class Consumer extends Thread{
private Queue queue;
String name;
int maxSize;
public Consumer(String name, Queue queue, int maxSize){
super(name);
this.name = name;
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run(){
while(true){
synchronized(queue){
while(queue.isEmpty()){
try {
System.out.println("Queue is empty, Consumer[" + name + "] thread is waiting for Producer");
queue.wait();
} catch (Exception ex) {
ex.printStackTrace();
}
}
int x = queue.poll();
System.out.println("[" + name + "] Consuming value : " + x);
queue.notifyAll();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
3.
/**
* 生产者消费者模式:使用Lock和Condition实现
* {@link java.util.concurrent.locks.Lock}
* {@link java.util.concurrent.locks.Condition}
*/
public class ProducerConsumerByLock {
private static final int CAPACITY = 5;
private static final Lock lock = new ReentrantLock();
private static final Condition fullCondition = lock.newCondition(); //队列满的条件
private static final Condition emptyCondition = lock.newCondition(); //队列空的条件
public static void main(String args[]){
Queue queue = new LinkedList();
Thread producer1 = new Producer("P-1", queue, CAPACITY);
Thread producer2 = new Producer("P-2", queue, CAPACITY);
Thread consumer1 = new Consumer("C1", queue, CAPACITY);
Thread consumer2 = new Consumer("C2", queue, CAPACITY);
Thread consumer3 = new Consumer("C3", queue, CAPACITY);
producer1.start();
producer2.start();
consumer1.start();
consumer2.start();
consumer3.start();
}
/**
* 生产者
*/
public static class Producer extends Thread{
private Queue queue;
String name;
int maxSize;
int i = 0;
public Producer(String name, Queue queue, int maxSize){
super(name);
this.name = name;
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run(){
while(true){
//获得锁
lock.lock();
while(queue.size() == maxSize){
try {
System.out .println("Queue is full, Producer[" + name + "] thread waiting for " + "consumer to take something from queue.");
//条件不满足,生产阻塞
fullCondition.await();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
System.out.println("[" + name + "] Producing value : +" + i);
queue.offer(i++);
//唤醒其他所有生产者、消费者
fullCondition.signalAll();
emptyCondition.signalAll();
//释放锁
lock.unlock();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/**
* 消费者
*/
public static class Consumer extends Thread{
private Queue queue;
String name;
int maxSize;
public Consumer(String name, Queue queue, int maxSize){
super(name);
this.name = name;
this.queue = queue;
this.maxSize = maxSize;
}
@Override
public void run(){
while(true){
//获得锁
lock.lock();
while(queue.isEmpty()){
try {
System.out.println("Queue is empty, Consumer[" + name + "] thread is waiting for Producer");
//条件不满足,消费阻塞
emptyCondition.await();
} catch (Exception ex) {
ex.printStackTrace();
}
}
int x = queue.poll();
System.out.println("[" + name + "] Consuming value : " + x);
//唤醒其他所有生产者、消费者
fullCondition.signalAll();
emptyCondition.signalAll();
//释放锁
lock.unlock();
try {
Thread.sleep(new Random().nextInt(1000));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}