Loading

多线程(多生产者-多消费者模式)

使用内部锁

要操作的MyValue类

package com.edu.productCustomerDesign;

/**
 * @作者 five-five
 * @创建时间 2020/9/23
 */
public class MyValue {
    private String val;
    private boolean isNotNull(){
        return this.val != null && this.val != "";
    }
    public void getVal() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (this){
            while (!isNotNull()){
                System.out.println(Thread.currentThread().getName()+"进入等待");
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+"取出值:\t"+val);
            this.val=null;
            //唤醒线程
            this.notifyAll();
        }
    }

    public void setVal() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        synchronized (this){
            while (isNotNull()){
                System.out.println(Thread.currentThread().getName()+"进入等待");
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            this.val=System.currentTimeMillis()+this.hashCode()+"";
            System.out.println(Thread.currentThread().getName()+"设置值:\t"+val);
            //唤醒线程
            this.notifyAll();
        }
    }
}

生产者线程

package com.edu.productCustomerDesign;


/**
 * @作者 five-five
 * @创建时间 2020/9/23
 */
public class ProductThread extends Thread {
    private MyValue value;

    public ProductThread(MyValue value) {
        this.value = value;
    }

    @Override
    public void run() {
        while (true) {
            value.setVal();
        }
    }
}

消费者线程

package com.edu.productCustomerDesign;


/**
 * @作者 five-five
 * @创建时间 2020/9/23
 */
public class CustomerThread extends Thread {
    private MyValue value;

    public CustomerThread(MyValue value) {
        this.value = value;
    }

    @Override
    public void run() {
        while (true) {
            value.getVal();
        }
    }
}

测试类

package com.edu.productCustomerDesign;

/**
 * @作者 five-five
 * @创建时间 2020/9/23
 */
public class Test {
    public static void main(String[] args) {
        MyValue value = new MyValue();
        ProductThread p1 = new ProductThread(value);
        CustomerThread c1 = new CustomerThread(value);
        ProductThread p2 = new ProductThread(value);
        CustomerThread c2 = new CustomerThread(value);
        ProductThread p3 = new ProductThread(value);
        CustomerThread c3 = new CustomerThread(value);
        p1.setName("p1");
        p2.setName("p2");
        p3.setName("p3");
        c1.setName("c1");
        c2.setName("c2");
        c3.setName("c3");
        p1.start();
        p2.start();
        p3.start();
        c1.start();
        c2.start();
        c3.start();
    }
}

测试结果图:

使用显示锁

package com.edu.lock.reentrant;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * <p>多生产者多消费者模式</p>
 *
 * @作者 five-five
 * @创建时间 2020/9/29
 */
public class Pro_cus {
    private String string = "";
    //定义一个显示锁
    public ReentrantLock lock = new ReentrantLock();
    //创建条件
    public Condition condition1 = lock.newCondition();

    //生产者线程
    public void setString() {
        try {
            //拿到锁对象
            lock.lock();
            Thread.sleep(500);
            System.out.println(Thread.currentThread().getName() + "======拿到了锁======");
            //开始判断如果string为空,则设置他的值,不为空则等待
            while (string == null || string == "") {
                String val = Math.random() + "";
                System.out.println(Thread.currentThread().getName() + "===开始设置string====" + val);
                string = val;
                condition1.signalAll();
            }
            //有值,等待
            System.out.println("string有值====" + Thread.currentThread().getName() + "========开始等待");
            condition1.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            System.out.println(Thread.currentThread().getName() + "========释放了锁");
            lock.unlock();
        }
    }

    //消费者线程
    public void getString() {
        try {
            //拿到锁对象
            lock.lock();
            Thread.sleep(500);
            System.out.println(Thread.currentThread().getName() + "======拿到了锁======");
            //开始判断如果string不为空,则得到他的值,且置空,为空则等待
            while (string != null && string != "") {
                System.out.println(Thread.currentThread().getName() + "===开始输出string====" + string);
                //将他置空
                string = "";
                //通知其他所有等待的线程
                condition1.signalAll();
            }
            //无值,等待
            System.out.println("string没值====" + Thread.currentThread().getName() + "========开始等待");
            condition1.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            //释放锁
            System.out.println(Thread.currentThread().getName() + "========释放了锁");
            lock.unlock();
        }
    }

    public static void main(String[] args) {
        Pro_cus cur = new Pro_cus();
        cur.string = "123";
        Runnable r1 = new Runnable() {
            @Override
            public void run() {
                cur.setString();
            }
        };
        Runnable r2 = new Runnable() {
            @Override
            public void run() {
                cur.getString();
            }
        };
        while (true) {
            new Thread(r2).start();
            new Thread(r1).start();
        }

    }

}

测试结果如图

 

posted @ 2020-09-23 10:04  揸火箭  阅读(133)  评论(0)    收藏  举报

Loading