一、使用同步代码块
package cn.et.deadlock;
import java.util.ArrayList;
import java.util.List;
public class Communication
{
public static void main(String[] args)
{
Person person = new Person();
new Thread(new Consumer( person),"消费者一").start();
new Thread(new Consumer(person),"消费者二").start();
new Thread(new Consumer(person),"消费者三").start();
new Thread(new Producer(person),"生产者一").start();
new Thread(new Producer(person),"生产者二").start();
new Thread(new Producer(person),"生产者三").start();
}
}
//生产者
class Producer implements Runnable
{
private Person person;
public Producer(Person person)
{
this.person = person;
}
@Override
public void run()
{
while (true)
{
try
{
person.produce();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
//消费者
class Consumer implements Runnable
{
private Person person;
public Consumer( Person person)
{
this.person = person;
}
@Override
public void run()
{
try
{
person.consume();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
class Person
{
private int foodNum = 0;
private Object synObj = new Object();
private final int MAX_NUM = 5;
//生产者方法
public void produce() throws InterruptedException
{
synchronized (synObj)
{
while (foodNum == 5)
{
System.out.println(Thread.currentThread().getName()+"来生产,仓库已满等待消费,数量 = " + foodNum);
synObj.wait();//等待并释放锁 在此被唤醒时 争抢CPU的资源 并往下执行
}
foodNum++;
System.out.println(Thread.currentThread().getName()+"生产成功,数量 = " + foodNum);
synObj.notifyAll();
}
}
//消费者方法
public void consume() throws InterruptedException
{
synchronized (synObj)
{
while (foodNum == 0)
{
System.out.println(Thread.currentThread().getName()+"来消费,仓库空了,数量 = " + foodNum);
synObj.wait();
}
foodNum--;
System.out.println(Thread.currentThread().getName()+"消费成功,数量 = " + foodNum);
synObj.notifyAll();
}
}
}
二、使用lock锁
package cn.et.lock;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class AwaitAndSignal
{
public static void main(String[] args)
{
Person person = new Person();
new Thread(new Consumer(person), "消费者一").start();
new Thread(new Consumer(person), "消费者二").start();
new Thread(new Consumer(person), "消费者三").start();
new Thread(new Producer(person), "生产者一").start();
new Thread(new Producer(person), "生产者二").start();
new Thread(new Producer(person), "生产者三").start();
}
}
//生产者
class Producer implements Runnable
{
private Person person;
public Producer(Person person)
{
this.person = person;
}
@Override
public void run()
{
for (int i = 0; i < 10; i++)
{
person.produce();
}
}
}
//消费者
class Consumer implements Runnable
{
private Person person;
public Consumer(Person person)
{
this.person = person;
}
@Override
public void run()
{
for (int i = 0; i < 10; i++)
{
person.consume();
}
}
}
class Person
{
private int foodNum = 0;
//获取lock锁对象
private ReentrantLock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
private final int MAX_NUM = 5;
//生产者方法
public void produce()
{
lock.lock();//获取锁
try
{
while (foodNum == MAX_NUM)
{
System.out.println(Thread.currentThread().getName()+"来生产,仓库已满,等待消费,数量= " + foodNum);
condition.await();
}
foodNum++;
System.out.println(Thread.currentThread().getName()+"生产数量= " + foodNum);
condition.signalAll();//唤醒所有等待线程。
}
catch(InterruptedException e)
{
e.printStackTrace();
} finally
{
lock.unlock();//释放锁
}
}
//消费者方法
public void consume()
{
lock.lock();
try
{
while (foodNum == 0)
{
System.out.println(Thread.currentThread().getName()+"来消费,仓库空了,数量 = " + foodNum);
condition.await();//造成当前线程在接到信号或被中断之前一直处于等待状态,并释放锁,等待被唤醒,唤醒时在此位置和别的线程争抢cpu
}
foodNum--;
System.out.println(Thread.currentThread().getName()+"来消费,数量 = " + foodNum);
condition.signalAll();//唤醒所有等待线程
}
catch(InterruptedException e)
{
e.printStackTrace();
} finally
{
lock.unlock();
}
}
}