使用同步锁来实现线程安全---生产者与消费者

当仓库满了时才允许消费者消费,当仓库为空时,才允许生产者生产

 

生产者类

package com.goodwe.entity;

import java.util.Queue;

/**
 * @Author : Wang Huyun
 * @Creation time : 2019/5/21  15:06
 * @Title:生产者
 */
public class Producer implements Runnable {
        private Queue<String> queue;

        private final int maxSize;

        public Producer(Queue<String> queue, int maxSize) {
                this.queue = queue;
                this.maxSize = maxSize;
        }

        @Override
        public void run() {
                produce();
        }

        void produce() {

                try {
                        synchronized (queue) {
                                while (true) {
                                        if (queue.size() == maxSize) {
                                                System.out.println("仓库已满,等待消费者消费!");
                                                queue.wait();
                                        }
                                        queue.add("产品");
                                        Thread.sleep(1000);
                                        System.out.println("生产者正在生产");
                                        queue.notifyAll();
                                }
                        }
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
        }
}

消费者类

package com.goodwe.entity;

import java.util.Queue;

/**
 * @Author : Wang Huyun
 * @Creation time : 2019/5/21  15:17
 * @Title:消费者
 */
public class Consumer implements Runnable {
        private Queue<String> queue;


        public Consumer(Queue<String> queue) {
                this.queue = queue;
        }

        @Override
        public void run() {
                consume();
        }

        void consume() {
                try {
                        synchronized (queue) {
                                while (true) {
                                        if (queue.isEmpty()) {
                                                System.out.println("仓库已空,等待生产者生产!");
                                                queue.wait();
                                                continue;
                                        }
                                        queue.remove();
                                        System.out.println("消费者正在消费");
                                        queue.notifyAll();
                                        Thread.sleep(1000);
                                }
                        }
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }

        }
}

主函数

 

package com.goodwe;


import com.goodwe.entity.Consumer;
import com.goodwe.entity.Producer;

import java.util.LinkedList;
import java.util.Queue;

public class Main {

        public static void main(String[] args) {
                Queue<String> queue = new LinkedList<>();
                int maxSize = 5;
                Thread producer = new Thread(new Producer(queue, maxSize));
                Thread consumer = new Thread(new Consumer(queue));
                producer.start();
                consumer.start();


        }


}

总结

作为生产者,当队列满时调用了队列的wait()方法,表示等待,并且此时释放了锁。作为消费者此时获取到锁并且移除队首元素时调用了notifyAll()方法,此时生产者由wait等待状态转换为唤醒状态,但注意!此时仅仅是线程被唤醒了,有了争夺CPU资源的资格,并不代表下一步就一定是生产者生产,还有可能消费者继续争夺了CPU资源。一定记住是被唤醒了,有资格争夺CPU资源。notifyAll()表示的是唤醒所有等待的线程,所有等待的线程被唤醒过后,都有了争夺CPU资源的权利,至于是谁会获得这个锁,那不一定。而如果是使用notify(),那就代表唤醒所有等待线程中的一个,只是一个被唤醒具有了争夺CPU的权力,其他没被唤醒的线程继续等待。如果等待线程就只有一个那么notify()和notifyAll()就没区别,不止一个那区别就大了,一个是只唤醒其中一个,一个是唤醒所有。唤醒不是代表这个线程就一定获得CPU资源一定获得锁,而是有了争夺的权利。

转载于:https://my.oschina.net/u/4100033/blog/3052322

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,理解了你的问题。生产者-消费者是一个经典的线程同步问题,需要使用线程和条件变量来实现。 首先,我们需要定义一个缓冲区,用来存储生产者生产的数据。缓冲区可以是一个队列或数组,缓冲区大小可以预先定义。 我们需要两个线程函数:生产者函数和消费者函数。生产者函数负责将数据写入缓冲区,消费者函数负责从缓冲区中读取数据。 我们还需要定义一些变量来实现线程同步,包括互斥和条件变量。 下面是一个简单的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define BUFFER_SIZE 10 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; //定义互斥 pthread_cond_t cond_producer = PTHREAD_COND_INITIALIZER; //定义生产者条件变量 pthread_cond_t cond_consumer = PTHREAD_COND_INITIALIZER; //定义消费者条件变量 int buffer[BUFFER_SIZE]; //定义缓冲区 int count = 0; //定义缓冲区计数器 void *producer(void *arg) //生产者函数 { int i; for (i = 0; i < 20; i++) //生产20个数据项 { pthread_mutex_lock(&lock); //加 while (count == BUFFER_SIZE) //缓冲区满,等待消费者消费 pthread_cond_wait(&cond_producer, &lock); buffer[count] = i; count++; printf("Producer produced item %d\n", i); pthread_cond_signal(&cond_consumer); //唤醒等待的消费者 pthread_mutex_unlock(&lock); //解 } pthread_exit(NULL); } void *consumer(void *arg) //消费者函数 { int i, item; for (i = 0; i < 20; i++) //消费20个数据项 { pthread_mutex_lock(&lock); //加 while (count == 0) //缓冲区空,等待生产者生产 pthread_cond_wait(&cond_consumer, &lock); item = buffer[count-1]; count--; printf("Consumer consumed item %d\n", item); pthread_cond_signal(&cond_producer); //唤醒等待的生产者 pthread_mutex_unlock(&lock); //解 } pthread_exit(NULL); } int main(int argc, char **argv) { pthread_t tid_producer, tid_consumer; pthread_create(&tid_producer, NULL, producer, NULL); pthread_create(&tid_consumer, NULL, consumer, NULL); pthread_join(tid_producer, NULL); pthread_join(tid_consumer, NULL); return 0; } ``` 以上代码使用了互斥和条件变量来实现生产者-消费者同步。具体实现可以参考代码注释。 希望对你有帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值