前言: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: 学习笔记