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

    一、小结

      1. 串行和并行

        串行:一个线程在处理操作 

        并行:多个线程在处理同一个操作

      2. 什么叫并发编程:再多线程环境下,应用程序的执行

      3. 并发编程 的目的:充分运用到资源,提高程序的效率

      4. 什么情况下用到并发编程 :

              4.1 在线程阻塞时,导致应用程序停止

              4.2 处理任务时间过长时2,可以创建子任务,来进行分段处理

              4.3 见端倪任务执行

    二、并发编程中待解决的问题

      1. 并发编程中频繁上下文切换问题

        频繁上下文切换,可能会带来一定的性能开销

        如何减少上下文性能开销:

                1.无锁编程

                2.CAS:Compare and Swap,是比较并交换的意思

                3. 使用最少线程数量

                4. 协程:在单线程环境下进行多任务调度,而一再多任务之间进行交换

      2. 并发编程中死锁问题

        多个线程在抢占资源,但是抢占过程当中资源如果被占用,会造成阻塞,如果多个线程互抢资源时,就会造成死锁情况,死锁会导致应用程序的阻塞

      编写测试代码

    public class DeadLockTest {
        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);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //薅第二个人的头发
                    synchronized (HAIR_A){
                        System.out.println("第二个人薅到了的第一个人的头发");
                    }
                }
    
            }).start();
        }
    }

      控制台效果

      命令窗口

      如何防止死锁问题

        1. 破坏请求和保持条件:在申请资源时,一次性将资源都申请到

        2. 破坏不可占用资源:抢占资源如何不满足,那就释放所有资源,以如果在需要则再次申请即可

        3. 破坏循环等待条件

      3. 线程安全问题

        多个线程同时操作同一个资源,可能会造成资源数据不安全问题

      编写 示例代码

      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(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //每一个 线程执行完毕,让计数减一
                    countDownLatch.countDown();
                }).start();
    
            }
            //等待计数器为0或者小0执行await下面代码
            countDownLatch.await();
            System.out.println(num);
        }

      解决方案一:

     private static int  num=0;
        //计算线程数量
        private static CountDownLatch countDownLatch=new CountDownLatch(10);
        //对资源进行操作
        public static  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(500);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    //每一个 线程执行完毕,让计数减一
                    countDownLatch.countDown();
                }).start();
    
            }
            //等待计数器为0或者小0执行await下面代码
            countDownLatch.await();
            System.out.println(num);
        }
  • 相关阅读:
    强化学习 相关资源
    Log4j输出文件到目的地
    httpclient 封装post 和get
    Cookie 和Session区别
    day09 request 和response
    Jmeter 断言
    Jmeter自学笔记10----性能测试基础实战
    Jmeter 目录
    性能测试解惑之并发压力
    设计模式,就是那个抽象工厂没写
  • 原文地址:https://www.cnblogs.com/szhhhh/p/12518219.html
Copyright © 2011-2022 走看看