java生产者和消费者使用wait() notify()
package com.company;
import java.util.ArrayList;
import java.util.List;
public class CP {
static class Factory{
List<Double> list = new ArrayList<>(5);
public synchronized void produce(){
if(list.size() == 5){
try {
wait();
System.out.println("wait currentThread = "+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
double temp = Math.random();
System.out.println("新增数据为 "+temp+"当前线程为 ="+Thread.currentThread().getName());
list.add(temp);
notifyAll();
}
}
public synchronized void consume(){
if(list.size() <= 0){
try {
System.out.println("wait currentThread = "+Thread.currentThread().getName());
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("删除数据 "+list.get(list.size()-1)+" 当前线程是 "+Thread.currentThread().getName());
list.remove(list.size()-1);
notifyAll();
}
}
}
static class ConsumeThread implements Runnable{
private Factory factory;
public ConsumeThread(Factory factory){
this.factory = factory;
}
@Override
public void run() {
while (true){
factory.consume();
}
}
}
static class ProducetThread implements Runnable{
private Factory factory;
public ProducetThread(Factory factory){
this.factory = factory;
}
@Override
public void run() {
while (true){
factory.produce();
}
}
}
public static void main(String[] args){
Factory factory = new Factory();
for(int i = 0; i < 5; i++){
ConsumeThread consumeThread = new ConsumeThread(factory);
new Thread(consumeThread).start();
ProducetThread producetThread = new ProducetThread(factory);
new Thread(producetThread).start();
}
}
}
使用ReenterLock实现生产者和消费者
package com.company;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/**
* 使用ReenterLock
*/
public class CP2 {
static class Factory{
private List<Double> list = new ArrayList<>();
private int max = 10;
ReentrantLock lock = new ReentrantLock();
Condition fullCondition = lock.newCondition();
Condition emptyCondition = lock.newCondition();
public void produce(){
lock.lock();
if(list.size() > max){
try {
fullCondition.await();
System.out.println("内存已满 暂停 "+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
} else {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("增加一条数据 "+Thread.currentThread().getName());
double next = Math.random();
list.add(next);
fullCondition.signalAll();
emptyCondition.signalAll();
}
lock.unlock();
}
public void consume (){
lock.lock();
if(list.size() <= 0){
try {
emptyCondition.await();
System.out.println("消耗完 "+Thread.currentThread().getName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.remove(0);
fullCondition.signalAll();
emptyCondition.signalAll();
System.out.println("消耗一个数据"+ Thread.currentThread().getName());
}
lock.unlock();
}
}
static class Product implements Runnable{
private Factory factory;
public Product(Factory factory){
this.factory = factory;
}
@Override
public void run() {
while (true){
factory.produce();
}
}
}
static class Consume implements Runnable{
private Factory factory;
public Consume(Factory factory){
this.factory = factory;
}
@Override
public void run() {
while (true){
factory.consume();
}
}
}
public static void main(String[] args){
Factory factory = new Factory();
for(int i =0; i < 5 ; i++){
Product p = new Product(factory);
new Thread(p).start();
Consume consume = new Consume(factory);
new Thread(consume).start();
}
}
}
使用阻塞队列,注意LinkedBlockQueue需要使用put方法加入数据而不是add
package com.company;
import java.util.concurrent.LinkedBlockingQueue;
public class CP3 {
private LinkedBlockingQueue<Double> queue = new LinkedBlockingQueue<>(10);
public void providuce(){
Double d = Math.random();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("新增数据 "+Thread.currentThread().getName());
try {
queue.put(d);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void consume(){
try {
System.out.println("删除数据 "+Thread.currentThread().getName());
Thread.sleep(400);
queue.take();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
static class Consume implements Runnable{
private CP3 cp;
public Consume(CP3 cp){
this.cp = cp;
}
@Override
public void run() {
while (true){
cp.consume();
}
}
}
static class Product implements Runnable{
private CP3 cp3;
public Product(CP3 cp3){
this.cp3 = cp3;
}
@Override
public void run() {
while(true){
cp3.providuce();
}
}
}
public static void main(String[] args){
CP3 cp = new CP3();
for(int i =0 ; i < 5; i++){
new Thread(new Consume(cp)).start();
new Thread(new Product(cp)).start();
}
}
}
使用信号量semahpore,他的使用方式和等待唤醒的方式类似。
package com.company;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
public class CP4 {
static Semaphore consumeSemaphore = new Semaphore(3);
static Semaphore productSemaphore = new Semaphore(2);
//一个线程读写
static Semaphore flagSemaphore = new Semaphore(1);
static List<Double> list = new ArrayList<>();
static class ConsumeThread implements Runnable{
@Override
public void run() {
while(true){
try {
consumeSemaphore.acquire();
flagSemaphore.acquire();
Thread.sleep(200);
if(list.size() > 0){
list.remove(0);
System.out.println("消耗数据 "+Thread.currentThread().getName());
}
flagSemaphore.release();
productSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
static class ProductThread implements Runnable{
@Override
public void run() {
while (true){
try {
productSemaphore.acquire();
flagSemaphore.acquire();
double d = Math.random();
Thread.sleep(300);
System.out.println("生产数据 "+Thread.currentThread().getName());
list.add(d);
flagSemaphore.release();
consumeSemaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args){
for(int i = 0; i < 5; i++){
new Thread(new ConsumeThread()).start();
new Thread(new ProductThread()).start();
}
}
}