前言:
貌似很久没更新了,更新一下最近以为自己已经了解,但是还是有一点错误的问题。
sychronized版本
需要注意:sychronized只允许有一个条件,即只有一个wait方法和notify方法,所以无论谁来唤醒,都会唤醒生成者和消费者,值得注意的地方是wait()方法会放弃锁,而sleep不会放弃锁,所以在判断条件处需要使用while来判断,因为当该线程从wait唤醒时,需要再次判断是否满足条件,而不是直接往下执行。
代码:
public class SychronizedDemo {
private volatile int number=0;
private final int FULL_NUMBER = 10;
private Object lock = new Object();
public static void main(String[] args) {
SychronizedDemo sychronizedDemo=new SychronizedDemo();
Thread pro01=new Thread(sychronizedDemo.new Productor());
pro01.setName("生产者01");
Thread pro02=new Thread(sychronizedDemo.new Productor());
pro02.setName("生产者02");
Thread con01=new Thread(sychronizedDemo.new Consumer());
con01.setName("消费者01");
Thread con02=new Thread(sychronizedDemo.new Consumer());
con02.setName("消费者02");
pro01.start();
pro02.start();
con01.start();
con02.start();
}
class Consumer implements Runnable {
@Override
public void run() {
int i = 0;
while (i < 10) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (lock) {
while (number <= 0) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number--;
System.out.println(Thread.currentThread().getName() + "消费了一个商品,还剩下" + number+ "个");
lock.notifyAll();
i++;
}
}
}
}
class Productor implements Runnable {
@Override
public void run() {
int i = 0;
while (i < 10) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
synchronized (lock) {
while (number >= FULL_NUMBER) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number++;
System.out.println(Thread.currentThread().getName() + "生成了一个商品,此时还有" + number + "个商品");
lock.notifyAll();
i++;
}
}
}
}
}
reentrantlock版本
reentrantlock则可以注册多个条件,每次可以只唤醒生成者,或者只唤醒消费者,在唤醒线程方面比较灵活,一样在判断条件处是需要循环判断。值得注意需要手动的获取锁以及手动的注册条件
public class ReentrantLockDemo {
private volatile int number = 0;
private final int FULL_NUMBER = 10;
private ReentrantLock lock = new ReentrantLock();
Condition isNull = lock.newCondition();
Condition isFull = lock.newCondition();
public static void main(String[] args) {
SychronizedDemo sychronizedDemo = new SychronizedDemo();
Thread pro01 = new Thread(sychronizedDemo.new Productor());
pro01.setName("生产者01");
Thread pro02 = new Thread(sychronizedDemo.new Productor());
pro02.setName("生产者02");
Thread con01 = new Thread(sychronizedDemo.new Consumer());
con01.setName("消费者01");
Thread con02 = new Thread(sychronizedDemo.new Consumer());
con02.setName("消费者02");
pro01.start();
pro02.start();
con01.start();
con02.start();
}
class Consumer implements Runnable {
@Override
public void run() {
int i = 0;
while (i < 10) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
lock.lock();
while (number <= 0) {
try {
isNull.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number--;
System.out.println(Thread.currentThread().getName() + "消费了一个商品,还剩下" + number + "个");
isFull.notifyAll();
i++;
lock.unlock();
}
}
}
class Productor implements Runnable {
@Override
public void run() {
int i = 0;
while (i < 10) {
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
lock.lock();
while (number >= FULL_NUMBER) {
try {
isFull.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
number++;
System.out.println(Thread.currentThread().getName() + "生成了一个商品,此时还有" + number + "个商品");
isNull.notifyAll();
i++;
lock.unlock();
}
}
}
}