在之前的Java多线程--生产者和消费者问题的初尝试中,使用的是Synchronized关键字来同步。本次将使用ReentrantLock锁对象来完成线程间的同步。
生产者代码:
package JavaDay5_19.JavaMultithreading;
import java.util.Queue;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author myvina@qq.com
* @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 myvina@qq.com
* @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 myvina@qq.com
* @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 myvina@qq.com
* @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();
}
}
}
}
}
测试结果如下:
总结:感觉两种同步方式各有各的优点,暂时还不太能分清,之后会再次介绍。