• Java基础-多线程


    以下纯属个人见解,如有不妥请及时指正以免误导他人!!!未完待续…..


    1.java多线程的实现方式有哪些?

    https://my.oschina.net/wugong/blog/1630778

    补(2018-4-3):实现线程的方式有Thread,Runnable,为什么有这两个方式?而不是Thread一个?
    即使不知道为什么,至少该理解一个最本质的事情!就是Thread是类,Runnable是接口,那么至少可以单纯从Java的单继承多实现的规则看待这个问题,甚至其次还有类和接口的区别去理解这样一个面试问题。


    2.线程池的实现原理?
           java线程池实现是解决资源有限的条件下,尽可能少的因为线程的创建销毁等时间等待和不必要的资源浪费。尽量使用创建好的线程去执行任务,那么来看,他的本质组成就肯定少不了这几个东西:一堆创建好的线程,或者预创建线程数目下可创建的线程,执行的任务,当任务多,但是线程数目有限的时候,对于任务的装载(队列)!以及,当队列满的时候,再有新来的任务的饱和处理策略,比如:是要直接丢弃,还是扔掉队列里面的最远或者最近的任务,执行它还是保存到硬盘或者数据库等等!由此可见,一些线程+队列+饱和处理策略=线程池的实现。

    可以参考以下我写过的文章:
    https://blog.csdn.net/kevin_king1992/article/details/79040053


    3.volatile是什么?有什么作用?如何实现的?
           volatile是用来修饰变量的,他可以保证变量在多线程环境下的可见性;禁止指令重排序。


    4.synchronized关键字怎么使用?对它深层的理解?
    1.含义:java中实现同步的关键字

    2.使用方法:
    a.修饰普通方法:锁是当前实例对象
    b.修饰静态方法:锁是当前类的Class对象
    c.同步代码块:锁是括号中的对象

    3.原理:
    同步代码块在编译后,前后分别加入monitorenter和monitorexit两个指令。进入代码块的只有一个线程,而线程必须获取锁monitor监视器。同步方法和同步代码块实现原理不同,但是也同样是使用这两个指令。


    5.显示锁都有哪些了解?怎么使用,和synchronized 关键字有什么不同,优势在哪里?
           synchronized 关键字是java提供的实现线程安全的方法之!它可以用在方法上实现同步方法或者实现同步代码块。它是虚拟机层面实现的,通过在字节码上 添加 monitorenter 和 monitorexit去实现,这两个指令只允许一个线程进入。相比起显示锁,synchronized 在JDK1.6之前可能性能稍逊色,但是之后进行优化已经和显示锁相差无几!

           显示锁主要有 ReentrantLock、ReentrantReadWriteLock,他们是可重入的独占式锁,提供了lock(),和unlock()方法!释放锁要写在finally块中,避免锁得不到释放!它还提供了Condition,可以有条件的(await和signal两个方法)进行操作。相比较起来synchronized 轻量灵活!

    https://my.oschina.net/wugong/blog/1631596


    6.生产者消费者模型


    7.线程间如何通讯?


    8.ConcurrentHashMap实现原理是什么?ConcurrentHashMap和HashMap区别?
           ConcurrentHashMap是java提供的线程安全的散列,HashMap是线程不安全的。ConcurrentHashMap主要使用了分段锁技术去实现Map集合的吞吐量和性能。HashMap如果想扩展为线程安全的可以借助于Collections.synchronizedMap方法,但是这种控制线程安全的方式是通过一个对象锁控制的,竞争它势必会在性能上大打折扣。


    9.java多线程中同步工具类有哪几个?都有什么作用或者使用场景?
    栅栏:CountDownLatch 允许一组线程相互等待完成!
    同步屏障:CyclicBarrier 允许一组线程相互等待,直到全部到达某个同步屏障点才开始一起执行任务!
    信号量:Semaphore 设置许可证,只允许<=许可证数量的线程进入执行任务!

    具体案例和使用方法参考下述文章:
    https://blog.csdn.net/kevin_king1992/article/details/79147313


    10.Condition是什么,怎么使用?

    https://my.oschina.net/wugong/blog/1632243


    11.什么是死锁?什么情况下会发生死锁?


    12.线程的定时任务如果定时时间小于任务的执行时间会怎么样?
    https://blog.csdn.net/kevin_king1992/article/details/79808426
    不会停,而是直到完成这个任务为止才会进行下一个!


    13.说一下常见的线程池? 2018-4-8
    https://mp.csdn.net/mdeditor/79040053 如果能记得清楚那当然就直接说了,如果记不清楚那么可以看一下几个实现的代码:

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    
    public static ExecutorService newFixedThreadPool(int nThreads) {
      return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }
    
    .......
    

    他们都是通过以下构造去实例的:

    public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) {
            if (corePoolSize < 0 ||
                maximumPoolSize <= 0 ||
                maximumPoolSize < corePoolSize ||
                keepAliveTime < 0)
                throw new IllegalArgumentException();
            if (workQueue == null || threadFactory == null || handler == null)
                throw new NullPointerException();
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }

    所以不同的实现就是构造参数的不同,理解好线程池的几个参数才是关键,比如说有的是核心线程=最大线程数,有的是核心线程是0,有的工作队列是有界阻塞队列,有的是无界阻塞队列,有的是对于线程池中线程的存活时间有限制等。


    14.锁优化相关! 2018-4-9 简单的说一下几个概念。
    自旋锁与自适应锁:自旋锁就是当一个县城获得锁执行的时候,另一个线程自己旋转而不是被挂起造成不必要的浪费!
    自适应就是自选不固定,而是由上一次在同一个锁上自选的时间及锁的拥有状态决定!

    偏向锁:在无竞争的情况下,把整个同步都消除,连CAS都不做;
    轻量级所:在无竞争的情况下使用CAS操作消除同步使用的互斥量。


    15.线程池参数的含义,比如:核心线程数1 最大线程数5,那么来三个任务,此时线程池中的线程数是几个??? 2018-4-11
    就是1个,再回顾一下线程池执行的逻辑:https://blog.csdn.net/kevin_king1992/article/details/79040053
    当核心线程数上限了,就会放入队列中等待空闲线程来处理,直到队列也满了,才会新建线程但是要小于最大线程数来处理队列中的任务!!!


    16.java多线程中的乐观锁与悲观锁?
    首先搞清楚悲观锁、乐观锁的宏观定义!其次,针对于数据库、和java语言本身提供的特性,他们又是很微观的。这里就说下java多线程机制下悲观锁和乐观锁!synchronized比较重,属于悲观锁,每次访问就认定可能操作,所以先竞争锁。乐观锁就是 偏向锁、轻量级锁、自旋锁等,假设没有冲突,冲突就空转等待,直到锁升级,尽量避免线程切换等不必要的开销。
    https://www.cnblogs.com/ygj0930/p/6561376.html
    https://blog.csdn.net/feeltouch/article/details/78330797


    java多线程的面试题目还有:
    http://www.cnblogs.com/jiahaoJAVA/p/6245127.html
    http://www.importnew.com/12773.html
    https://my.oschina.net/u/3739863/blog/1796263

  • 相关阅读:
    异步/同步、阻塞/非阻塞的理解
    轻量级交互数据json格式初探
    linux服务器开发浅谈
    linux守护进程解读
    OpenStack securityGroup rule Set
    OpenStack ceilometer部署安装监控,计费数据抓取测试Ok
    OpenStack high-level Functionsenabled
    控制系统音量,自己定义MPVolumeView
    windows 用户变量和系统变量的差别
    反汇编基本原理与x86指令构造
  • 原文地址:https://www.cnblogs.com/Kevin-1992/p/12608379.html
Copyright © 2020-2023  润新知