生产者消费者问题。
生产者产生一个产品放置在仓库里,若没消费者来消费则,线程等待不再生产,当产品被消费者消费时就应该通知生产者再唤醒线程再生产内容。
所以关键因素为:
1、产品 content;
2、生产产品的方法(Product.makeValue),消费产品的方法(Customer.getTheMsg)
3、生产者在生产时阻塞其他线程,不让他们消费,完毕时再唤醒其他线程;消费者在消费时阻塞其他线程,不让他们生产,消费完毕时,唤醒消费者再继续生产。
public class SyncTest {
private static String content="";
private static class Product{
private final Object lock ;
public Product(Object lock) {
this.lock = lock;
}
public void makeValue(){
synchronized (lock){
try{
if (!"".equals(content)) {
lock.wait();
}
content=Thread.currentThread().getName()+" this is "+System.currentTimeMillis();
System.out.println(content);
lock.notify();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
public static class Customer{
private final Object lock;
public Customer(Object lock) {
this.lock = lock;
}
public void getTheMsg(){
synchronized (lock){
try{
if ("".equals(content)) {
lock.wait();
}
System.out.println(Thread.currentThread().getName()+" get the msg "+content);
content="";
lock.notifyAll();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
Object lock = new Object();
Product product = new Product(lock);
Customer customer = new Customer(lock);
Thread thread1 = new Thread(()->{
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println("makeValue---index---->"+i);
product.makeValue();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1");
Thread thread2 = new Thread(()->{
try {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println(" getValue---index---->"+i);
customer.getTheMsg();
}
}catch (InterruptedException e){
e.printStackTrace();
}
},"t2");
thread1.start();
thread2.start();
}
}
这里的锁应该是生产者和消费者共用一把锁,如果使用不同的对象锁则不会产生相同的效果。
使用ReentrantLock 和Condition的消费者生产者。
public class LoclTest {
private static String content="";
private static class Product{
private ReentrantLock lock;
private Condition condition;
public Product(ReentrantLock lock, Condition condition) {
this.lock = lock;
this.condition = condition;
}
public void makeTheValue(){
lock.lock();
try{
if (!"".equals(content)) {
this.condition.await();
}
content=Thread.currentThread().getName()+" : "+System.currentTimeMillis();
System.out.println(content);
this.condition.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
private static class Customer{
private ReentrantLock lock;
private Condition condition;
public Customer(ReentrantLock lock, Condition condition) {
this.lock = lock;
this.condition = condition;
}
public void getValue(){
lock.lock();
try {
if ("".equals(content)) {
condition.await();
}
System.out.println(Thread.currentThread().getName()+" get value is "+content);
content="";
condition.signal();
}catch (Exception e){
e.printStackTrace();
}finally {
lock.unlock();
}
}
}
public static void main(String[] args) {
ReentrantLock lock = new ReentrantLock();
Condition condition = lock.newCondition();
Product product = new Product(lock,condition);
Customer customer = new Customer(lock,condition);
Thread thread1 = new Thread(()->{
for (int i = 0; i < 10; i++) {
product.makeTheValue();
}
},"t1");
Thread thread2 = new Thread(()->{
for (int i = 0; i < 10; i++) {
customer.getValue();
}
},"t2");
thread1.start();
thread2.start();
}
}