本学习笔记学习内容来自尚硅谷周阳老师:
package geovis.demo;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Cake {
private Integer number = 0;
public synchronized void production() throws Exception{
//判断
// if(number !=0 ){
// wait();
// }
while(number !=0 ){
wait();
}
//操作
number++;
System.out.println(Thread.currentThread().getName()+"生产了:"+number);
//通知
this.notifyAll();
}
public synchronized void consume() throws InterruptedException{
// if(number == 0){
// wait();
// }
while (number == 0){
wait();
}
number--;
System.out.println(Thread.currentThread().getName()+"消费完还剩:"+number);
this.notifyAll();
}
}
/**
* 多线程开发生产者消费者
* 1.搞内聚低耦合下,线程操作资源类
* 2.判断/操作/通知
* 3.防止多线程虚假唤醒
* 只有A和B交替生产消费时使用if判断是否等待没问题,
* 但是如果再添加C和D生产消费四个就有问题,需要使用
* while循环判断来确定是否真的被唤醒
*/
public class CurrentTreadSynchronized {
public static void main(String[] args) {
Cake cake = new Cake();
new Thread(() -> {
for (int i=0;i<10;i++) {
try {
cake.production();
} catch (Exception e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(() -> {
for (int i=0;i<10;i++) {
try {
cake.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(() -> {
for (int i=0;i<10;i++) {
try {
cake.production();
} catch (Exception e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(() -> {
for (int i=0;i<10;i++) {
try {
cake.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();
}
}
/**
* 以上是使用老版本的synchronized加锁的方式实现生产消费的,synchronized的等待和通知使用的是Object父类的方法实现的
*
* 下面的两个类使用的是juc的lock锁实现生产消费的,lock锁的通知方式为使用Condition接口的await和signal方法实现的
*/
class CakeLock {
private Integer number = 0;
private Lock lock = new ReentrantLock();
private Condition condition = lock.newCondition();
public void production() {
lock.lock();
try {
while (number != 0){
condition.await();
}
number++;
System.out.println(Thread.currentThread().getName()+"生产了:" + number);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void consume() {
lock.lock();
try {
while (number == 0){
condition.await();
}
System.out.println(Thread.currentThread().getName()+"消费了:"+number--);
condition.signalAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
class CurrentTreadLock{
public static void main(String[] args) {
CakeLock cakeLock = new CakeLock();
new Thread(()->{
for (int i=0;i<10;i++){
cakeLock.production();
}
},"A").start();
new Thread(()->{
for (int i=0;i<10;i++){
cakeLock.consume();
}
},"B").start();
new Thread(()->{
for (int i=0;i<10;i++){
cakeLock.production();
}
},"C").start();
new Thread(()->{
for (int i=0;i<10;i++){
cakeLock.consume();
}
},"D").start();
}
}