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);
        }
  • 相关阅读:
    商贸通帐套隐藏方法
    固定资产打开提示:上年度数据未结转!
    ZOJ 2432 Greatest Common Increasing Subsequence
    POJ 1080 Human Gene Functions
    POJ 1088 滑雪
    POJ 1141 Brackets Sequence
    POJ 1050 To the Max
    HDOJ 1029 Ignatius and the Princess IV
    POJ 2247 Humble Numbers
    HDOJ 1181 变形课
  • 原文地址:https://www.cnblogs.com/szhhhh/p/12518219.html
Copyright © 2011-2022 走看看