请看以下代码安全
/** * @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=""; }
输出结果ide
.... 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装填,则程序就不在执行任何业务功能了,整个项目处于停滞状态。this
请看以下代码线程
/** * @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方法只能保证一次唤醒一个程序,若是唤醒的程序不是异类程序而是同类程序,好比生产者唤醒生产者,若是一直这样运行下去,可能会致使全部的程序都陷入等待状态。code
解决假死的方法,当出现多生产多消费的时候,唤醒线程的时候唤醒全部的线程,即便用notifyAll方法,这样就能保证不出现假死的状况了。ip
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(); } } }