线程同步生产者和消费者c和java不同实现

javac 分别实现下消费者 生产者模式,更好的理解如何通过互斥锁条件变量来保证资源同步


java

    package com.toc;

    import java.util.LinkedList;
    import java.util.concurrent.TimeUnit;

    public class MutexCond {

        private static LinkedList<Integer> list = new LinkedList<Integer>();

        public static void main(String[] args) throws InterruptedException {
            Thread pThread = new Thread(new Producer(list));
            Thread cThread = new Thread(new Consumer(list));
            pThread.start();
            cThread.start();
            pThread.join();
            cThread.join();
        }

        public static class Producer implements Runnable{

            private LinkedList<Integer> pList;
            public Producer(LinkedList<Integer> list) {
                this.pList = list;
            }
            int capacity = 10 ;
            int value = 0 ;
            @Override
            public void run() {
                while(true){
                    // 上锁的对象pList
                    synchronized (pList) {
                        if (pList.size() == capacity) {
                            try {
                                // 就要由上锁的对象wait,从而释放锁,如果是this,可以省略不写
                                // 容易出错
                                pList.wait();
                            } catch (InterruptedException e) {
                            }
                        }
                        System.out.println("Producer produced + " + value);
                        value ++ ;
                        pList.add(value);
                        // 上锁对象notify
                        pList.notify();
                        try {
                            TimeUnit.SECONDS.sleep(1);
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }

        }

        public static class Consumer implements Runnable{
            private LinkedList<Integer> cList;
            public Consumer(LinkedList<Integer> list) {
                this.cList = list;
            }

            @Override
            public void run() {
                while(true){
                    synchronized (cList) {
                        if(list.size() == 0){
                            try {
                                cList.wait();
                            } catch (InterruptedException e) {
                            }
                        }
                        int val = cList.removeFirst();
                        System.out.println("Consumer consumed ----- " + val);
                        cList.notify();
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                        }
                    }
                }
            }
        }
    }

c

    // 生产者-消费者的例子,生产者生产一个结构体串在链表的表头上,消费者从表头取走结构体。

    #include <stdlib.h>
    #include <pthread.h>
    #include <stdio.h>

    struct msg {
        struct msg *next;
        int num;
    };

    struct msg *head;
    pthread_cond_t has_product = PTHREAD_COND_INITIALIZER;
    pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;

    void *consumer(void *p)
    {
        struct msg *mp;

        for (;;) {
            pthread_mutex_lock(&lock);
            while (head == NULL)
                pthread_cond_wait(&has_product, &lock);
            mp = head;
            head = mp->next;
            pthread_mutex_unlock(&lock);
            printf("Consume %d\n", mp->num);
            free(mp);
            sleep(rand() % 5);
        }
    }

    void *producer(void *p)
    {
        struct msg *mp;
        for (;;) {
            mp = malloc(sizeof(struct msg));
            pthread_mutex_lock(&lock);
            mp->next = head;
            mp->num = rand() % 1000;
            head = mp;
            printf("Produce %d\n", mp->num);
            pthread_mutex_unlock(&lock);
            pthread_cond_signal(&has_product);
            sleep(rand() % 5);
        }
    }

    int main(int argc, char *argv[]) 
    {
        pthread_t pid, cid;  

        srand(time(NULL));
        pthread_create(&pid, NULL, producer, NULL);
        pthread_create(&cid, NULL, consumer, NULL);
        pthread_join(pid, NULL);
        pthread_join(cid, NULL);
        return 0;
    }

总结

c

  • c在linux下是通过引入互斥锁(Mutex,Mutual Exclusive Lock) 来实现线程之间的同步的。获得锁的线程可以完成“读-修改-写”的操作,然后释放锁给其它线程,没有获得锁的线程只能等待而不能访问共享数据,这样“读-修改-写”三步操作组成一个原子操作,要么都执行,要么都不执行,不会执行到中间被打断,也不会在其它处理器上并行做这个操作。

  • Mutex用pthread_mutex_t类型的变量表示,可以这样初始化和销毁:

    #include <pthread.h>

    int pthread_mutex_destroy(pthread_mutex_t *mutex);
    int pthread_mutex_init(pthread_mutex_t *restrict mutex,
           const pthread_mutexattr_t *restrict attr);
// 如果Mutex变量是静态分配的(全局变量或static变量),也可以用宏定义PTHREAD_MUTEX_INITIALIZER来初始化,相当于用pthread_mutex_init初始化并且attr参数为NULL
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
  • 返回值:成功返回0,失败返回错误号。

  • 线程间的同步还有这样一种情况:线程A需要等某个条件成立才能继续往下执行,现在这个条件不成立,线程A就阻塞等待,而线程B在执行过程中使这个条件成立了,就唤醒线程A继续执行。在pthread库中通过条件变量(Condition Variable)来阻塞等待一个条件,或者唤醒等待这个条件的线程。Condition Variablepthread_cond_t类型的变量表示,可以这样初始化和销毁:

    #include <pthread.h>

    int pthread_cond_destroy(pthread_cond_t *cond);
    int pthread_cond_init(pthread_cond_t *restrict cond,
           const pthread_condattr_t *restrict attr);
    pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

java

  • 在java中synchronized其实也是一种互斥锁,而配合waitnotify notifyAll方法,同样实现了条件变量,实现了线程的同步。

  • 有一点需要注意的是,加锁的对象一定要明确,给谁加的锁,必须由谁来waitnotify,否则会抛出监视对象不一致的异常。当加锁对象是this时,wait和notify可以省略,但是一定要明确给谁加的。可以改动上面的例子,试着抛出monitor不一致的异常。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值