請看以下代碼安全
/** * @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(); } } }