Java多线程--生产者和消费者问题的再尝试

在之前的Java多线程--生产者和消费者问题的初尝试中,使用的是Synchronized关键字来同步。本次将使用ReentrantLock锁对象来完成线程间的同步。

生产者代码:

package JavaDay5_19.JavaMultithreading;

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

/**
 * @author [email protected]
 * @date 18-5-19  上午10:33
 */

public class Producer implements Runnable {
    private Queue<Integer> products;
    private ReentrantLock lock;

    public Producer(Queue<Integer> products, ReentrantLock lock) {
        this.products = products;
        this.lock = lock;
    }

    @Override
    public void run() {
        for(int i = 0; i <= 4; i++) {
            try {
                lock.lock();
                if(products.size() == 2) {
                    System.out.println("存货已满");
                    i--;
                } else {
                    products.offer(i);
                    System.out.println("Producing " + i);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

消费者代码:

package JavaDay5_19.JavaMultithreading;

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

/**
 * @author [email protected]
 * @date 18-5-19  上午10:22
 */

public class Consumer implements Runnable {
    private Queue<Integer> products;
    private ReentrantLock lock;

    public Consumer(Queue<Integer> products, ReentrantLock lock) {
        this.products = products;
        this.lock = lock;
    }

    @Override
    public void run() {
        while(true) {
            try {
                lock.lock();
                if (products.isEmpty()) {
                    System.out.println("商品缺货...");
                } else {
                    int number = products.poll();
                    System.out.println("Consuming " + number);
                    if (number == 4) {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

测试代码:

package JavaDay5_19.JavaMultithreading;

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author [email protected]
 * @date 18-5-19  上午10:38
 */

public class Test {
    public static void main(String[] args) {
        Queue<Integer> product = new LinkedList<>();
        ReentrantLock lock = new ReentrantLock();
        Thread producer = new Thread(new Producer(product, lock));
        Thread consumer = new Thread(new Consumer(product, lock));

        producer.start();
        consumer.start();
    }
}

运行结果:



将Producer类中sleep时间改为3后,代码如下:

package JavaDay5_19.JavaMultithreading;

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

/**
 * @author [email protected]
 * @date 18-5-19  上午10:33
 */

public class Producer implements Runnable {
    private Queue<Integer> products;
    private ReentrantLock lock;

    public Producer(Queue<Integer> products, ReentrantLock lock) {
        this.products = products;
        this.lock = lock;
    }

    @Override
    public void run() {
        for(int i = 0; i <= 4; i++) {
            try {
                lock.lock();
                if(products.size() == 2) {
                    System.out.println("存货已满");
                    i--;
                } else {
                    products.offer(i);
                    System.out.println("Producing " + i);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
                try {
                    Thread.sleep(3);//此处改为3
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

测试结果如下:



总结:感觉两种同步方式各有各的优点,暂时还不太能分清,之后会再次介绍。

猜你喜欢

转载自blog.csdn.net/weixin_41704428/article/details/80372519
今日推荐