第三章-线程之间的通讯-第二篇

生产者消费者模式

请看以下代码安全

/**
 * @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();
        }
    }
}
相关文章
相关标签/搜索