多线程编程 之生产者消费者

为了提高CPU的利用率和各线程之间相互协作,Java的一种实现线程间通信的机制是:wait/notify线程间通信,下边就一起学习一下这种线程间的通信机制。

  • wait方法

(1)方法wait()的作用是使当前执行代码的线程进行等待,并且在wait()所在的代码处停止执行,直到接到通知或被中断为止。

(2)在调用wait()之前,线程必须获得该对象级别锁,这是一个很重要的地方,很多时候我们可能会忘记这一点,即只能在同步方法或同步块中调用wait()方法。

(3)还需要注意的是wait()是释放锁的,即在执行到wait()方法之后,当前线程会释放锁,当从wait()方法返回前,线程与其他线程竞争重新获得锁

  • notify方法

(1)和wait()方法一样,notify()方法也要在同步块或同步方法中调用,即在调用前,线程也必须获得该对象的对象级别锁。

(2)该方法是用来通知那些可能等待该对象的对象锁的其他线程,如果有多个线程等待,则由线程规划器随机挑选出其中一个呈wait状态的线程,对其发出通知notify,并使它等待获取该对象的对象锁。

(3)这里需要注意的是,执行notify方法之后,当前线程不会立即释放其拥有的该对象锁,而是执行完之后才会释放该对象锁,被通知的线程也不会立即获得对象锁,而是等待notify方法执行完之后,释放了该对象锁,才可以获得该对象锁。

(4)notifyAll()通知所有等待同一共享资源的全部线程从等待状态退出,进入可运行状态,重新竞争获得对象锁。

SyncStack 栈

public class SyncStack {

    private int Max = 3;

    private int index=0; 

    ArrayList list=new ArrayList();

    public synchronized void create(Object object) throws Exception {
        while (index >= Max) {
            this.wait();
        }
        this.notify();

        index++;
        list.add(object);

        System.out.println("生产了第 "+index+" 个");
    }

    public synchronized void cosume() throws Exception{
        while(index<=0){
            this.wait();
        }
        this.notify();
        index--;
        list.remove(0);

        System.out.println("消费了第 "+index+" 个");
    }
}

生产者线程

public class Producer implements Runnable {

    SyncStack stack = null;

    public Producer(SyncStack stack) {
        this.stack = stack;
    }

    @Override
    public void run() {
        while(true){
            try {
                stack.create("面包");
                Thread.sleep(1000);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

消费者线程

public class Consumer implements Runnable {

    SyncStack stack = null;

    public Consumer(SyncStack stack) {
        this.stack = stack;
    }

    @Override
    public void run() {
        while(true){
            try {
                stack.cosume();
                Thread.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        SyncStack stack = new SyncStack();
        Producer producer = new Producer(stack);
        Producer produce2r = new Producer(stack);
        Consumer consumer = new Consumer(stack);
        try {
            new Thread(producer).start();
            Thread.sleep(4000);
            new Thread(consumer).start();
            //new Thread(produce2r).start();

        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

结果:

生产了第 1 个
生产了第 2 个
生产了第 3 个
消费了第 2 个
生产了第 3 个
消费了第 2 个
生产了第 3 个
消费了第 2 个
消费了第 1 个
生产了第 2 个
消费了第 1 个
消费了第 0 个
生产了第 1 个
消费了第 0 个
生产了第 1 个
消费了第 0 个
生产了第 1 个
消费了第 0 个

猜你喜欢

转载自blog.csdn.net/qq_35830949/article/details/79585207