• 并发编程(一)


    一、小结

      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);
        }
  • 相关阅读:
    Android 开发 框架系列 OkHttp拦截器
    Android 开发 框架系列 OkHttp文件上传功能实现(含断点续传)
    Android 开发 框架系列 OkHttp使用详解
    Android 开发 框架系列 OkHttp文件下载功能实现(含断点续传)
    Git 如何使用ssh上传或者同步/下载项目到github
    Git 获取项目git clone
    System.arraycopy复制数组方法解释
    Android开发 AAC的ADTS头解析[转载]
    Android开发 多媒体提取器MediaExtractor详解_将一个视频文件分离视频与音频
    Android开发 多媒体提取器MediaExtractor详解_入门篇
  • 原文地址:https://www.cnblogs.com/szhhhh/p/12518219.html
Copyright © 2020-2023  润新知