zoukankan      html  css  js  c++  java
  • 并发编程

    并发编程专题内容:
      串行和并行:
       串行:一个线程在处理操作
       并行:多个线程在处理同一个操作
      什么叫做并发编程:在多线程环境下,应用程序的执行
      并发编程的目的:充分运用到资源,提高程序的效率
      什么情况下用到并发编程:
       1.在线程阻塞时,导致应用程序停止
       2.处理任务时间过长时,可以创建子任务,来进行分段处理
       3.间断任务执行
       
      
      一.并发编程中待解决的问题
       1.并发编程中频繁上下文切换的问题
        频繁上下文切换,可能会带来一定的性能开销
        如何减少上下文性能开销:
         1.无锁并发编程
         2.CAS
         3.使用最少线程数量
         4.协程:在单线程环境下进行多任务的调度,可以在多任务之间进行任务切换
       
       
       2.并发编程中死锁问题
        多个线程在抢占资源,但是抢占过程当中资源如果被占用,会造成阻塞,如果多个线程互抢资源时,就会造成死锁情况,死锁会导致应用程序的阻塞
        
        案例: 
         public class DeadLockDemo {
          //资源
          private static final Object HAIR_A=new Object();
          private static final Object HAIR_B=new Object();
          public static void main(String[] args) {
           //第一个人
           new Thread(()->{
            //护住自己的头发
            synchronized (HAIR_A){
             System.out.println("第一个人护住自己的头发,准备薅第二个人的头发");
             //延迟时间
             try {
              Thread.sleep(100);
             } catch (InterruptedException e) {
              e.printStackTrace();
             }
             //薅第二个人的头发
             synchronized (HAIR_B){
              System.out.println("第一个人薅到了第二个人的头发");
             }
            }
           }).start();

           //第二个人
           new Thread(()->{
            //护住自己的头发
            synchronized (HAIR_B){
             System.out.println("第二个人护住自己的头发,准备薅第一个人的头发");
             //延迟时间
             try {
              Thread.sleep(100);      //当前线程休眠,让渡CPU资源
             } catch (InterruptedException e) {
              e.printStackTrace();
             }
             //薅第一个人的头发
             synchronized (HAIR_A){
              System.out.println("第二个人薅到了第一个人的头发");
             }
            }
           }).start();
          }
         }
        如何预防死锁问题:
         1.破坏请求和保持条件:在申请资源时,一次性将资源都申请到
         2.破坏不可占用条件:抢占资源如何不满足,那就释放所有资源,以后如果再需要则再次申请即可
         3.破坏循环等待条件
         
       3.线程安全问题
        多个线程同时操作同一个资源,可能会造成资源数据不安全问题
        
        示例:
         public class UnsafeThread {
          //资源
          private static int num=0;
          //计算线程数量
          private static CountDownLatch countDownLatch=new CountDownLatch(10);
          //对资源进行操作
          public static void inCreate(){
           num++;
          }

          public static void main(String[] args) throws InterruptedException {
           for (int i = 0 ; i < 10 ; i++ ){
            new Thread(()->{
             for (int j = 0 ; j < 100; j++){
              inCreate();
              try {
               Thread.sleep(100);
              } catch (InterruptedException e) {
               e.printStackTrace();
              }
             }
             //每一个线程执行完毕,让计数-1
             countDownLatch.countDown();
            }).start();
           }
           //等待计数器为0或者小于0执行await下面代码
           countDownLatch.await();
           System.out.println(num);
          }
         }
        
        解决线程不安全问题:
         public class UnsafeThread {
          //资源
          private static int num=0;
          //计算线程数量
          private static CountDownLatch countDownLatch=new CountDownLatch(10);
          private static ReentrantLock reentrantLock = new ReentrantLock();
          //对资源进行操作
          public static  void inCreate(){
           //上锁
           reentrantLock.lock();
           num++;
           reentrantLock.unlock();

          }
          
          public static synchronized void inCreate(){
           //上锁
           
           num++;
           

          }
          
          public static synchronized void inCreate(){
           //上锁
           synchronized(UnsafeThread.class){
            num++;
           }
          }

          public static void main(String[] args) throws InterruptedException {
           for (int i = 0 ; i < 10 ; i++ ){
            new Thread(()->{
             for (int j = 0 ; j < 100; j++){
              inCreate();
              try {
               Thread.sleep(100);
              } catch (InterruptedException e) {
               e.printStackTrace();
              }
             }
             //每一个线程执行完毕,让计数-1
             countDownLatch.countDown();
            }).start();
           }
           //等待计数器为0或者小于0执行await下面代码
           countDownLatch.await();
           //获取到当前计数器中的线程数量
           /*while (true){
            if(countDownLatch.getCount()<=5){
             System.out.println(num);
             break;
            }
           }*/
           System.out.println(num);

          }
         }
  • 相关阅读:
    js指定区域全屏
    sql中对日期的筛选
    SQL Server查询死锁,杀死进程解决死锁
    SqlServer数据类型、C#SqlDbType对应关系及转换
    用SqlDataReader返回多个结果集
    SQL重复记录查询的几种方法
    IIS支持10万个同时请求的设置
    常量与变量的命名法则
    远程服务器返回错误: (405) 不允许的方法。
    The view 'Index' or its master was not found or no view engine supports the
  • 原文地址:https://www.cnblogs.com/mayuan01/p/12519209.html
Copyright © 2011-2022 走看看