zoukankan      html  css  js  c++  java
  • JUC(个人笔记一)以及对应的面试题

    什么是JUC?
    java.util.current
    Runnable:没有返回值,效率相比Callable相对较低

    2、线程和进程
    进程:一个程序,QQ.exe Music.exe 程序的集合
    一个进程往往可以包含多个线程,至少包含一个!
    java默认有几线程? 2个 main、GC线程
    线程:开了一个进程Typor,写字,自动保存(线程负责的)
    **java真的能开启线程吗?**开不了(java是没有权限的)
    在这里插入图片描述

    并发、并行
    并发(多线程操作同一个资源)
    比如CPU一核,模拟出来多条线程,天下武功,为快不破,快速交替(产生一个假象)
    并行(多个人一起行走)
    比如CPU多核,多个线程可以同时执行
    获取CPU核数
    并发编程的本质,充分利用CPU的资源(企业为了提高效率)

    线程有几个状态(查看源码得知)
    线程新生(NEW)
    线程运行(RUNABLE)
    线程阻塞(BLOCKED)
    线程等待(WAITING)死死的等
    超时等待(TIME_WAITING)
    终止(TERMINATED)

    wait和sleep区别
    1、首先他们来自不同的类
    wait—》Object
    sleep–》Thread
    企业中,休眠,会用(java.util.current.TimeUnit这个类)
    2、关于锁的释放
    wait会释放锁,而sleep会持有锁(抱着锁睡觉,不会释放)
    3、使用的范围不同
    wait必须在同步代码块中
    sleep可以在任何地方睡
    4、是否需要捕获异常
    wait不需要捕获异常
    sleep必须要捕获异常

    3、Lock锁(重点)
    传统Synchronized(本质:队列,锁)
    真正的多线程开发,公司中的开发,降低耦合性,线程就是一个单独的资源类,没有任何的附属操作(属性、方法)

    Lock接口
    在这里插入图片描述
    lock源码
    RentrantLock
    公平锁:十分公平:可以先来后到
    非公平锁:十分不公平:可以插队(默认)
    在这里插入图片描述
    Lock锁和Synchronized区别
    1、Synchronized 内置java关键字,Lock是一个java类
    2、Synchronized 无法判断获取锁的状态,Lock可以判断是否获取到了锁
    3、Synchronized 会自动释放锁,而Lock锁必须要手动释放锁。如果不释放锁,会产生死锁
    4、Synchronized 线程一(获得锁、阻塞)、线程二(等待,傻傻的等);Lock锁就不一定会等待下去(lock.tryLock() 尝试获取锁)
    5、Synchronized可重入锁,不可以中断的,非公平;Lock,可重入锁,可以判断锁,非公平(可以自己设置);
    6、Synchronized 适合锁少量的代码同步问题;Lock适合锁大量的同步代码块
    4、生产者和消费者问题
    面试的算法:单例模式、8大排序算法、生产者和消费者、死锁
    Synchronized版:
    在这里插入图片描述
    问题存在,A、B、C、D四个线程,还安全吗?存在虚假唤醒if判断改为while判断
    在这里插入图片描述

    JUC版的生产者和消费者问题
    在这里插入图片描述
    代码实现
    在这里插入图片描述
    在这里插入图片描述
    Condition任何一个新的技术,绝对不是仅仅为了覆盖原来的技术,优势和补充!
    Condition精准的通知和唤醒线程(ABC线程顺序执行)
    在这里插入图片描述
    在这里插入图片描述
    5、锁是什么?如何判断锁的是谁?8锁现象
    如何判断锁的是谁? 对象、Class
    深刻理解锁
    Synchronized锁的对象是方法的调用者!
    在这里插入图片描述
    小结:
    new出来的 this 具体的一个手机
    static Class 唯一的一个模板

    6、集合类不安全(并发下不安全)

    List不安全

    package com.itheima.kiki.demo01;
    
    import java.util.*;
    import java.util.concurrent.CopyOnWriteArrayList;
    
    /**
     * @author zs
     * @version 1.0
     * @create 2020/6/4 13:32
     */
    //java.util.ConcurrentModificationException 并发修改异常
    public class ListTest {
        public static void main(String[] args) {
    //        List<String> list = Arrays.asList("1", "2", "3");
    //        list.forEach(System.out::println);
            //并发下ArrayList是不安全的
            /**
             * 解决方案:
             * 1、List<String> list = new Vector<>();  Vector jdk1.0就出现了
             * 2、List<String> list = Collections.synchronizedList(new ArrayList<>());
             * 3、List<String> list = new CopyOnWriteArrayList<>();// JUC解决方案
             */
            //List<String> list = new ArrayList<>(); //ArrayList jdk1.2
            //List<String> list = new Vector<>();
    
            //让ArrayList变得安全
            //List<String> list = Collections.synchronizedList(new ArrayList<>());
    
            //CopyOnWrite 写入时复制,简称COW 计算机程序设计领域的 一种优化策略
            //多线程调用的时候,List 读取的时候,是固定的,但是写入的时候可能存在覆盖操作
            //在写入的时候避免覆盖造成数据问题
            //读写分离 MyCat
            //CopyOnWriteArrayList比 Vector牛逼在哪个地方?
            //Vetor 底层用了Synchronized关键字,只要有Synchronized的地方效率就会低
            //而CopyOnWriteArrayList 底层使用的Lock锁
    
            List<String> list = new CopyOnWriteArrayList<>();// JUC解决方案
            for (int i = 1; i <=10 ; i++) {
                new Thread(()->{
                    list.add(UUID.randomUUID().toString().substring(0,5));
                    System.out.println(list);
                },String.valueOf(i)).start();
    
            }
            
        }
    }
    
    

    学习方法:
    1、先会用
    2、货比三家,寻找其他解决方案
    3、分析源码

    Set不安全

    package com.itheima.kiki.demo01;
    import java.util.Set;
    import java.util.UUID;
    import java.util.concurrent.CopyOnWriteArraySet;
    /**
     * @author zs
     * @version 1.0
     * @create 2020/6/4 14:20
     */
    /**
     * 同理可证 java.util.ConcurrentModificationException 并发修改异常
     *  解决方案:
     *          1:Set<String> set = Collections.synchronizedSet(new HashSet<>());
     *          2:Set<String> set = new CopyOnWriteArraySet<>();
     */
    public class SetTest {
        public static void main(String[] args) {
            //HashSet<String> set = new HashSet<>();
            //Set<String> set = Collections.synchronizedSet(new HashSet<>());
            Set<String> set = new CopyOnWriteArraySet<>();
            for (int i = 1; i <= 10; i++) {
                new Thread(()->{
                    set.add(UUID.randomUUID().toString().substring(0,5));
                    System.out.println(set);
                },String.valueOf(i)).start();
            }
        }
    }
    

    HashSet的底层是什么?

        public HashSet() {
            map = new HashMap<>();
        }
    //add  set的本质就是map  key是无法重复的并且是无序的
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
        private static final Object PRESENT = new Object();  //不变的值
    

    Map也是不安全的
    回顾map的基本操作
    在这里插入图片描述

    package com.itheima.kiki.demo01;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.UUID;
    import java.util.concurrent.ConcurrentHashMap;
    /**
     * @author zs
     * @version 1.0
     * @create 2020/6/4 14:38
     */
    /**java.util.ConcurrentModificationException 并发修改异常
     * 解决方案:
     *  1、Map<String, String> map = new ConcurrentHashMap<>();
     */
    public class MapTest {
        public static void main(String[] args) {
            //map 是这样用的吗?不是,工作中不用这个
            // 默认等价于什么? new HashMap<>(0.75,16); //加载因子、初始化容量
    
            //Map<String, String> map = new HashMap<>();
            Map<String, String> map = new ConcurrentHashMap<>();
            for (int i = 1; i <= 30; i++) {
                new Thread(()->{
                    map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
                    System.out.println(map);
                },String.valueOf(i)).start();
            }
        }
    }
    

    7、Callable
    在这里插入图片描述
    1、可以有返回值
    2、可以抛出异常
    3、方法不同 run()/ call()
    代码测试
    在这里插入图片描述
    在这里插入图片描述

    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.Future;
    import java.util.concurrent.FutureTask;
    
    /**
     * @author zs
     * @version 1.0
     * @create 2020/6/4 15:00
     */
    /**
     * 1、探究原理
     * 2、觉得自己会用
     */
    public class CallableTest {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //new Thread(new MyThread()).start();
            //new Thread(new Runnable()).start();
            //new Thread(new FutureTask<V>()).start();
            //new Thread(new FutureTask<V>(Callable)).start();
            new Thread().start();//怎么启动callable
            MyThread thread = new MyThread();
            //适配类
            FutureTask futureTask = new FutureTask(thread);
            new Thread(futureTask,"A").start();
            new Thread(futureTask,"B").start(); //结果会被缓存,效率高
            String o = (String) futureTask.get();//获取Callable的返回结果,这个get方法可能会产生阻塞!把它放在最后,或者使用异步通信来处理
            System.out.println(o);
        }
    }
    
    //class MyThread implements Runnable{
    //    @Override
    //    public void run() {
    //    }
    //}
    class  MyThread implements Callable<String>{
        @Override
        public String call() {
            System.out.println("call()");
            //耗时的操作
            return "123456";
        }
    }
    

    细节:
    1、有缓存
    2、结果可能会要等待,会阻塞!
    (内容接第二部分https://blog.csdn.net/qq_38616503/article/details/106559170)

  • 相关阅读:
    OpenCV 使用FLANN进行特征点匹配
    OpenCV 特征描述
    OpenCV 特征点检测
    OpenCV 亚像素级的角点检测
    OpenCV Shi-Tomasi角点检测子
    OpenCV Harris 角点检测子
    OpenCV 模板匹配
    OpenCV 直方图计算
    OpenCV 直方图均衡化
    OpenCV 仿射变换
  • 原文地址:https://www.cnblogs.com/kiki-study/p/13656083.html
Copyright © 2011-2022 走看看