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

原文地址:https://www.cnblogs.com/Kevin-1992/p/12608379.html