J2C_CopyOnWriteArrayList读时共享写时复制_2_读写锁_进程之间不可通过全局变量通信

/************************************************Java********************************************/

/*
 * 写时复制容器 Copy on write
 * 写的效率低,读的效率高
 * 将原容器拷贝一份,写操作则作用在新的副本上,需加锁,此过程中若有读操作则会作用在原容器上
 */

CopyOnWriteArrayList

/********************************Java****************************************/
/*
 * 写时复制容器 Copy on write
 * 写的效率低,读的效率高
 * 将原容器拷贝一份,写操作则作用在新的副本上,需加锁,此过程中若有读操作则会作用在原容器上
 */
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.CopyOnWriteArrayList;

public class CopyWriteList_value {

    public static void main(String[] args) {
        final List<String> lists=
            /*
                这个会出并发问题,效率很高,但会出现一致性问题
                new ArrayList<>();
            */ 
            /*
                加锁的,效率低一些,保证一致性
                new Vector(); 
            */
            /*
												写时复制容器,每一次往里加一个数据都要复制一份,耗时间,耗内存
												读的时候,效率高,多线程读的时候不用加锁
												适用在写的很少,读的很多
												写时加锁,读不需要加锁
											  */
            new CopyOnWriteArrayList<>(); 

	    final Random r=new Random();
	    Thread[] ths=new Thread[100];

      /*
       * 起100个线程
       */
        for(int i=0;i<ths.length;i++){
	    Runnable task=new Runnable() {
	        public void run() {
	            //每个线程往容器里加1000个数
		    for(int i=0;i<1000;i++) lists.add("a"+r.nextInt(10000));
		}
	    };
	    ths[i]=new Thread(task);
	}
	runAndComputeTime(ths); //计算线程运行时间
	System.out.println(lists.size());  //10万个
    }


    static void runAndComputeTime(Thread[] ths){
	long s1=System.currentTimeMillis();
	for (Thread t : ths) {
	    t.start(); //启动线程
	    try {
		t.join(); //让“主线程”等待“子线程”结束之后才能继续运行,是一个阻塞函数,
	    } catch (InterruptedException e) {
		e.printStackTrace();
	    }
	}
	long s2=System.currentTimeMillis();
	System.out.println(s2-s1);
    }

}

/****************************************C*****************************************/
/*
 *读写锁,读加锁可以共享,即重复加;写操作独占; 且写的优先级大于读的优先级
 *写操作需加锁,此过程中若有读操作则会阻塞;读操作需加锁,此过程中若有读操作也会加锁成功
 */

pthread_rwlock_t lock;


/****************************************C*****************************************/
/*
 *读写锁,读加锁可以共享,即重复加;写操作独占; 且写的优先级大于读的优先级
 *写操作需加锁,此过程中若有读操作则会阻塞;读操作需加锁,此过程中若有读操作也会加锁成功
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <pthread.h>  

int number=0; //定义一个全局变量


pthread_rwlock_t lock; //1---创建读写锁

void* write_func(void* arg)
{
    while(1)
    {
	pthread_rwlock_wrlock(&lock); //加写锁
	number++;
	printf("==write:%lu, %d\n",pthread_self(),number);
	pthread_rwlock_unlock(&lock); //解锁 
	usleep(500);  //休眠500微秒
    }
    return NULL;
}
void* read_func(void* arg)
{
    while(1)
    {
	pthread_rwlock_rdlock(&lock); //加读锁
	printf("==read:%lu, %d\n",pthread_self(),number);
	pthread_rwlock_unlock(&lock); //解锁
	usleep(500);  //休眠500微秒
    }
    return NULL;
}


int main(int argc,const char* argv[]) //在main函数中的方法属于父线程
{
    pthread_rwlock_init(&lock,NULL); //2---初始化读写锁

    pthread_t p[8]; 
    int i=0;
    for(i=0;i<3;++i)  //循环创建3个写线程
    {
	pthread_create(&p[i],NULL,write_func,NULL);  
    }
    for(i=3;i<8;++i)  //循环创建5个读线程
    {
	pthread_create(&p[i],NULL,read_func,NULL);  
    }
    

    for(i=0;i<8;++i)
    {
	pthread_join(p[i],NULL); //阻塞回收子线程的pcb
    }

   
    pthread_rwlock_destroy(&lock);  //3---释放读写锁资源

    return 0;
    
}

/*************************************C***************************/
/*
 *    读时共享同一块内存区,写时会复制
 *    进程之间不可通过全局变量通信    
 */

/*************************************C***************************/
/*
 *	读时共享同一块内存区,写时会复制
 *	进程之间不可通过全局变量通信	
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>

int counter = 200;
int main(int argc,const char* argv[])
{
   int number=3;
   int i=0;
   pid_t pid;
   
   for(i=0;i<number;++i)
   {
      pid = fork();
      if(pid == 0)  
      {
          break;  //如果是子进程,那么直接跳出该循环,不让他继续生子进程
      }
   }
  
  if(i==0)   //第一个子进程
  {
     counter += 200;
     printf("first process,pid=%d\n",getpid());
     printf("---第一个子进程-------counter = %d\n",counter);
  } 
  if(i==1)  
  {
     
     counter += 200;
     printf("second process,pid=%d\n",getpid());
     printf("---第二个子进程-------counter = %d\n",counter);
  }

  if(i==2)   
  {
     counter += 200;
     printf("thread process,pid=%d\n",getpid());
     printf("---第三个子进程-------counter = %d\n",counter);
  }
  if(i==number)   //上面的for循环执行完毕,父进程便跳出循环,执行这里
  {
     counter += 400;
     printf("father process,pid=%d\n",getpid());
     printf("---父进程-------counter = %d\n",counter);
  }
   return 0;
}

猜你喜欢

转载自blog.csdn.net/zs_life/article/details/88932766