生产者消费者模式
请看如下代码
/**
* @program: demo
* @description: 生产者
* @author: lee
* @create: 2018-08-29
**/
public class Product {
private String lock;
public Product(String lock) {
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
if (!ValueObjec.value.equals("")) {
lock.wait();
}
String value = System.currentTimeMillis() + "_"+ System.nanoTime();
System.out.println("set的值是"+value);
ValueObjec.value=value;
lock.notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
/**
* @program: demo
* @description: 消费者
* @author: lee
* @create: 2018-08-29
**/
public class Consume {
private String lock;
public Consume() {
}
public Consume(String lock) {
this.lock = lock;
}
public void getValue() {
try {
synchronized (lock) {
if (ValueObjec.value.equals("")) {
lock.wait();
}
String value = ValueObjec.value;
System.out.println("get的值是"+value);
ValueObjec.value="";
lock.notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
/**
* @program: demo
* @description: 主线程
* @author: lee
* @create: 2018-08-29
**/
public class Run {
public static void main(String[] args) {
String lock = new String("");
Thread thread = new Thread(new ThreadA(new Product(lock)));
thread.start();
Thread thread2 = new Thread(new ThreadB(new Consume(lock)));
thread2.start();
}
}
/**
* @program: demo
* @description: 线程
* @author: lee
* @create: 2018-08-29
**/
public class ThreadA implements Runnable {
private Product product;
public ThreadA(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
product.setValue();
}
}
}
/**
* @program: demo
* @description: 线程
* @author: lee
* @create: 2018-08-29
**/
public class ThreadB implements Runnable{
private Consume consume;
public ThreadB(Consume consume) {
this.consume = consume;
}
@Override
public void run() {
while (true) {
consume.getValue();
}
}
}
/**
* @program: demo
* @description: demo
* @author: lee
* @create: 2018-08-29
**/
public class ValueObjec {
public static String value="";
}
输出结果
....
get的值是1535543013723_95467291931143
set的值是1535543013723_95467291970255
get的值是1535543013723_95467291970255
set的值是1535543013723_95467292002650
get的值是1535543013723_95467292002650
set的值是1535543013723_95467292034255
get的值是1535543013723_95467292034255
set的值是1535543013723_95467292055588
get的值是1535543013723_95467292055588
set的值是1535543013723_95467292076526
get的值是1535543013723_95467292076526
set的值是1535543013723_95467292117612
...
多生产多消费
假死状态就是线程进入waiting等待的状态,如果全部线程都进入waiting装填,则程序就不在执行任何业务功能了,整个项目处于停滞状态。
请看如下代码
/**
* @program: demo
* @description: 消费者
* @author: lee
* @create: 2018-08-29
**/
public class Consume {
private String lock;
public Consume() {
}
public Consume(String lock) {
this.lock = lock;
}
public void getValue() {
try {
synchronized (lock) {
if (ValueObjec.value.equals("")) {
System.out.println("消费者" + Thread.currentThread().getName() + "*********进入等待*******");
lock.wait();
}
String value = ValueObjec.value;
System.out.println("get的值是"+value);
ValueObjec.value="";
lock.notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
/**
* @program: demo
* @description: 生产者
* @author: lee
* @create: 2018-08-29
**/
public class Product {
private String lock;
public Product(String lock) {
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
if (!ValueObjec.value.equals("")) {
System.out.println("生产者" + Thread.currentThread().getName() + "*********进入等待*******");
lock.wait();
}
String value = System.currentTimeMillis() + "_"+ System.nanoTime();
System.out.println("set的值是"+value);
ValueObjec.value=value;
lock.notify();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
/**
* @program: demo
* @description: 主线程
* @author: lee
* @create: 2018-08-29
**/
public class Run {
public static void main(String[] args) {
String lock = new String("");
Thread thread = new Thread(new ThreadA(new Product(lock)));
thread.start();
Thread thread2 = new Thread(new ThreadA(new Product(lock)));
thread2.start();
Thread thread3 = new Thread(new ThreadA(new Product(lock)));
thread3.start();
Thread threadB = new Thread(new ThreadB(new Consume(lock)));
threadB.start();
Thread threadB1 = new Thread(new ThreadB(new Consume(lock)));
threadB1.start();
Thread threadB2 = new Thread(new ThreadB(new Consume(lock)));
threadB2.start();
Thread threadB3 = new Thread(new ThreadB(new Consume(lock)));
threadB3.start();
}
}
/**
* @program: demo
* @description: 线程
* @author: lee
* @create: 2018-08-29
**/
public class ThreadA implements Runnable {
private Product product;
public ThreadA(Product product) {
this.product = product;
}
@Override
public void run() {
while (true) {
product.setValue();
}
}
}
/**
* @program: demo
* @description: 线程
* @author: lee
* @create: 2018-08-29
**/
public class ThreadB implements Runnable{
private Consume consume;
public ThreadB(Consume consume) {
this.consume = consume;
}
@Override
public void run() {
while (true) {
consume.getValue();
}
}
}
/**
* @program: demo
* @description: demo
* @author: lee
* @create: 2018-08-29
**/
public class ValueObjec {
public static String value="";
}
这个多生产多消费的程序很不安全,因为notify方法只能保证一次唤醒一个程序,如果唤醒的程序不是异类程序而是同类程序,比如生产者唤醒生产者,如果一直这样运行下去,可能会导致所有的程序都陷入等待状态。
假死解决办法
解决假死的方法,当出现多生产多消费的时候,唤醒线程的时候唤醒所有的线程,即使用notifyAll方法,这样就能保证不出现假死的情况了。
public class Consume {
private String lock;
public Consume() {
}
public Consume(String lock) {
this.lock = lock;
}
public void getValue() {
try {
synchronized (lock) {
if (ValueObjec.value.equals("")) {
System.out.println("消费者" + Thread.currentThread().getName() + "*********进入等待*******");
lock.wait();
}
String value = ValueObjec.value;
System.out.println("get的值是"+value);
ValueObjec.value="";
lock.notifyAll();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
public class Product {
private String lock;
public Product(String lock) {
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
if (!ValueObjec.value.equals("")) {
System.out.println("生产者" + Thread.currentThread().getName() + "*********进入等待*******");
lock.wait();
}
String value = System.currentTimeMillis() + "_"+ System.nanoTime();
System.out.println("set的值是"+value);
ValueObjec.value=value;
lock.notifyAll();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}