J2C_CountDownLatch_2_信号量_比较

前言:Java的门栓即闭锁与C的信号量

    Java                                                                                         C

//1变成0,门就开了                                          sem_wait(&produce_sem);  //produce_sem==0,阻塞

//调用一次countDown()自减1                           sem_post(&custom_sem); //custom_sem++,通知消费者消费

//并且自身线程也可以向下执行                         sem_wait(&custom_sem); //custom_sem==0,阻塞

CountDownLatch                                              sem_post(&produce_sem); //produce_sem++

 

/**************************************Java********************************/
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

public class CountDownLatch_Value {
    volatile List lists=new ArrayList();
    public void add(Object o){
	lists.add(o);
    }
    public int size(){
	return lists.size();
    }

    public static void main(String[] args) {
	final CountDownLatch_Value c=new CountDownLatch_Value();
	//闭锁,即信号量,即门栓
	//效率最高,并发最好
	final CountDownLatch latch=new CountDownLatch(1); //1变成0,门就开了
		
	/*
         *  线程1
         */
	new Thread(new Runnable() {
	    public void run() {
	        System.out.println("t1启动");
		for(int i=0;i<10;i++){
		    c.add(new Object());
		    System.out.println("add"+i);
		    if(c.size()==5){
                 //调用一次countDown()自减1,打开门栓,让t2得以执行,并且自身线程也可以向下执行
		         latch.countDown();	
		    }
		    try {
			Thread.sleep(1000);
		    } catch (InterruptedException e) {
			e.printStackTrace();
		    }
		}
	    }
	},"t1").start();
		

	/*
         *  线程2
         */
	new Thread(new Runnable() {
	    public void run() {
		System.out.println("t2启动"); //先启动起来
		if(c.size()!=5){
		    try{
		        latch.await(); //门栓等待,不需要锁定任何对象,线程阻塞在这里
		        //latch.await(5000,TimeUnit.MILLISECONDS)) //也可以指定等待时间
		    }catch(InterruptedException e){
		        e.printStackTrace();
		    }
	        }
	        System.out.println("t2结束");
	    }
	},"t2").start();
	
	try {
            Thread.sleep(1000);
	} catch (InterruptedException e) {
	    e.printStackTrace();
	}		
    }
}


/*******************************C***************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>  
#include <semaphore.h>

sem_t produce_sem; //生产者与消费者信号量
sem_t custom_sem;

typedef struct node  
{
   int data;  //数据域
   struct node* next; //指针域
}Node;

Node* head=NULL;

/*
 *生产者
 */
void* producer(void* arg)
{
    while(1)
    {
	sem_wait(&produce_sem); //produce_sem==0,阻塞//produce_sem--
	Node* node = (Node*)malloc(sizeof(Node)); //malloc返回值是void*,强制转换(Node*)
	node->data = rand()%1000;  //(0-999)
	node->next = head;
	head=node; 	
	printf("======生产者:%lu,%d\n",pthread_self(),node->data);
	sem_post(&custom_sem); //custom_sem++,通知消费者消费//释放资源

	sleep(rand()%5);  //休息5秒以内,取余数
    }
    return NULL;
}

/*
 *    消费者
 */
void* customer(void* arg)
{
    while(1)
    {        
        //custom_sem==0,阻塞//等待生产者操作custom_sem++,然后解除阻塞开始执行
        sem_wait(&custom_sem); 
	Node* del=head;  //定义一个变量
	head=head->next;  //头指针向下一个节点移动
	printf("--------消费者:%lu,%d\n",pthread_self(),del->data);
	free(del);	
	sem_post(&produce_sem); //produce_sem++//释放资源//资源还给生产者

	sleep(rand()%5);
    }
    return NULL;
}


int main(int argc,const char* argv[]) //在main函数中的方法属于父线程
{
   
    //0,代表线程同步。1,代表进程同步//4,代表最多有四个线程可以同时操作共享数据
    sem_init(&produce_sem,0,4); 
    sem_init(&custom_sem,0,0);  //初始化消费者线程信号量

    pthread_t thid[2]; 
    pthread_create(&thid[0],NULL,producer,NULL); //创建线程
    pthread_create(&thid[1],NULL,customer,NULL);  
  
    int i=0;
    for(i=0;i<2;++i)    
    {
	pthread_join(thid[i],NULL); //阻塞等待回收子线程的pcb
    }

    sem_destroy(&produce_sem);  //3---销毁信号量
    sem_destroy(&custom_sem);

    return 0;
    
}

 

mark: 学习笔记

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值