需求:使用多个线程实现资源的一存一取交替执行。
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
这是资源类(存放商品信息)
*/
class Commodity{
private String name ; //商品名
private int num = 1; //商品编号
private boolean flag = false; //标记是否已有商品存在
Lock lock = new ReentrantLock(); //锁
//这两个对象用来等待和唤醒生产和消费线程
Condition conpro = lock.newCondition(); //绑定锁的生产者监视器
Condition concus = lock.newCondition(); //绑定锁的消费者监视器
public void produce(String name) throws InterruptedException
{
lock.lock(); //上锁
try
{
//如果已经有了商品,则无需再生产,生产线程被等待
while (flag)
conpro.await();
this.name = name + " "+num+++"号";
System.out.println("生产了一个"+this.name);
flag = true; //生产一个商品之后,标记为true
concus.signal(); //唤醒一个消费线程
}
finally
{
//因为无论如何,在执行完该段代码之后都必须要解锁,因此unlock方法在finally代码段中
lock.unlock();
}
}
public void consumption() throws InterruptedException
{
lock.lock(); //上锁
try
{
//如果此时没有商品,则消费线程被等待
while (!flag)
concus.await();
System.out.println("消费了一个"+this.name);
flag = false; //消费掉商品之后,将标记置为false
conpro.signal(); //消费掉商品之后,唤醒一个生产线程
}
finally
{
//因为无论如何,在执行完该段代码之后都必须要解锁,因此unlock方法在finally代码段中
lock.unlock();
}
}
}
/*
这是一个生产线程类,通过实现Runnable接口
*/
class Producer implements Runnable{
Commodity com ; //商品(资源)引用
public Producer(Commodity com) //通过构造函数传入一个商品(资源)对象
{
this.com = com;
}
public void run() //覆盖run()
{
while (true)
{
try {
com.produce("商品"); //调用生产商品的方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/*
这是一个消费线程类,通过实现Runnable接口
*/
class Customer implements Runnable{
Commodity com ;//商品(资源)引用
public Customer(Commodity com) //通过构造函数传入一个商品(资源)对象
{
this.com = com;
}
public void run() //覆盖run()
{
while (true) {
try {
com.consumption(); //调用消费方法
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
/*
主类,完成生产和消费线程的创建和开启
*/
public class UltTest {
public static void main(String[] args) {
Commodity com = new Commodity(); //资源对象
//创建生产、消费对象并传入资源对象
Producer pro = new Producer(com);
Customer cus = new Customer(com);
//创建线程对象并传入实现Runnable接口的类对象
Thread t1 = new Thread(pro);
Thread t2 = new Thread(pro);
Thread t3 = new Thread(cus);
Thread t4 = new Thread(cus);
//开启线程
t1.start();
t2.start();
t3.start();
t4.start();
}
}