生产者、消费者问题

线程六个状态:

  public enum State {
        /**
         * 新生
         */
        NEW,

        /**
         * 运行
         */
        RUNNABLE,

        /**
         *阻塞
         */
        BLOCKED,

        /**
         * 等待
         */
        WAITING,

        /**
         * 超时等待
         */
        TIMED_WAITING,

        /**
            死亡
         **/
        TERMINATED;
    }

 synchronized和lock的区别

1、synchronized是关键字,lock是类

2、synchronized全自动获取释放,lock手动

3、synchronized标识后,线程A执行,线程B会一直等待,lock可以中途释放

4、synchronized适合少量的数代码,lock用于大亮代码加锁。

经典问题,生产者、消费者

 public static void main(String[] args) {
        t2 t2 = new t2();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                try {
                    t2.add();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
        new Thread(() -> {
            for (int i = 0; i < 50; i++) {
                try {
                    t2.delete();
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        }).start();
    }

        int sum = 0;

    public synchronized void add() throws InterruptedException {
        //while(sum==0)    
        if (sum != 0) {
            this.wait();
        }
        sum++;
        System.out.println(sum + "生产了一个东西");
        this.notify();
    }

    public synchronized void delete() throws InterruptedException {
        //while(sum==0)    
        if (sum == 0) {

            this.wait();
        }
        sum--;
        System.out.println(sum + "使用了一个东西");
        this.notify();
    }

以上代码看着和用着都没问题,问题出在,一旦我多几个线程运行就会出现数据错误:

生产者、消费者问题_第1张图片

而且还有几率一直某一个线程处于等待状态,无法被唤醒 :

生产者、消费者问题_第2张图片

我的理解是cpu执行的数据很快,假如在某一刻A线程处于等待,B线程也处于等待,此时C线程唤醒了,这两个同时被唤醒,就出现了多次消费,虚假唤醒,其实就只能消费一次。

所以我们不能使用一次if作为判断,应该使用while作为判断,

然后就是使用java多线程包下的Condition ,它也可以阻塞、唤醒线程,它还有一个优势就是可以指定唤醒某一个线程。

package com.quxiao.controller;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @program: package1
 * @author: quxiao
 * @create: 2023-09-27 15:22
 **/
public class t3 {
    public static void main(String[] args) {
        t3 t3 = new t3();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                t3.a();
            }
        }, "a").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                t3.b();
            }
        }, "b").start();
        new Thread(() -> {
            for (int i = 0; i < 10; i++) {
                t3.c();
            }
        }, "c").start();
    }

    int sum = 1;
    Lock lock = new ReentrantLock();
    Condition aLock = lock.newCondition();
    Condition bLock = lock.newCondition();
    Condition cLock = lock.newCondition();

    void a() {
        lock.lock();
        try {
            while (sum != 1) {
                aLock.await();
            }
            System.out.println(Thread.currentThread().getName()+":" + "AAAA");
            sum = 2;
            bLock.signal();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }

    }

    void b() {
        lock.lock();
        try {
            while (sum != 2) {
                bLock.await();
            }
            System.out.println(Thread.currentThread().getName()+":" + "BBBB");
            sum = 3;
            cLock.signal();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }

    }

    void c() {
        lock.lock();
        try {
            while (sum != 3) {
                cLock.await();
            }
            System.out.println(Thread.currentThread().getName()+":" + "CCCC");
            sum = 1;
            aLock.signal();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }

    }
}

你可能感兴趣的:(多线程,java,开发语言)