35.并行和并发有什么区别?
(1)并行是指两个或者多个事件在同一时刻发生;而并发是指两个或者多个事件同一 时间间隔发生。
(2)并行是在不同实体上的多个对象,而并发是在同一个实体的多个对象。
(3)在一台机器上同时处理多个任务,在多台机器上同时处理多个任务。如hadoop分布式集群
36.线程和进程的区别?
进程是操作系统进行资源分配和调度的一个独立单位;线程是进程的一个实体,是CPU调度和分派的基本单位,是比进程更小的能独立运行的基本单位。线程的划分尺度小于进程,这使得多线程程序的并发性高;进程在执行时通常拥有独立的内存单元,而线程之间可以共享内存。
37.守护线程是什么?
守护线程(daemon thread),是个服务线程,准确地来说就是服务其他的线程,这是它的作用——而其他的线程只有一种,那就是用户线程。所以java里线程分2种。 1.守护线程,比如垃圾回收线程,就是最典型的守护线程。 2.用户线程,就是应用程序里的自定义线程。
38.创建线程有哪几种方式?
Java5以前实现多线程有两种方式。一种是继承Thread类,另一种是Runnable接口。两种方式都要通过重写run()方法来定义线程的行为,推荐使用后者。Java 5以后创建线程还有第三种方式:实现Callable接口,该接口中的call方法可以在线程执行结束时产生一个返回值。
39.说一下 runnable 和 callable 有什么区别?
Runnable接口中run()方法返回值是void,而Callable接口中的call()方法是有返回值的是一个泛型。和Future、FutureTask配合可以用来获取异步执行的结果。
40.线程有哪些状态?

41.sleep() 和 wait() 有什么区别?
sleep()方法是线程类的静态方法,调用此方法会让当前线程暂停执行指定时间,将执行机会(CPU)让给其它线程,但是对象的锁依然保持,因此休眠时间结束后自动恢复,也就是就绪状态。wait()是Object类的方法,调用wait()方法会导致当前线程放弃对象的锁(线程暂停执行),进入对象等待池,只有调用notify()或者notifyAll()方法才可以将其唤醒进入等锁池,如果线程重新获得对象的锁就可以进入就绪状态。
42.notify()和 notifyAll()有什么区别?
notify():唤醒处于一个等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且与优先级无关。
notifyAll():唤醒所有处于等待状态的线程,该对象并不是将对象的锁给所有线程,而是让他们竞争,只有获得锁的线程才能进入就绪状态。
43.线程的 run()和 start()有什么区别?
我们也可以换个说法,启动一个线程是调用run()方法还是start()方法?
start()方法是启动一个线程的,使线程所代表的虚拟机处于一个可运行状态,这意味它可以由JVM调度并执行,但不意味着线程就会立即执行。 run方法是线程启动后要进行回调(callback)的方法,只是一个普通函数。
所以多线程执行时是使用start()方法而不是run()方法。
44.创建线程池有哪几种方式?
newSingleThreadExecutor: 创建一个单线程的线程池。 这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。 如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。 此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
newFixedThreadPool: 创建固定大小的线程池。 每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。 线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。
newCachedThreadPool: 创建一个可缓存的线程池。 如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。 此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
newScheduledThreadPool: 创建一个大小无限的线程池。 此线程池支持定时以及周期性执行任务的需求。
newSingleThreadExecutor: 创建一个单线程的线程池。 此线程池支持定时以及周期性执行任务的需求。
45.线程池都有哪些状态? 线程池的5种状态:RUNNING、SHUTDOWN、STOP、TIDYING、TERMINATED。

46.线程池中 submit()和 execute()方法有什么区别?
(1)接受的参数不一样
(2)submit()有返回值,而execute没有返回值
(3)submit方便Exception处理
47.在 java 程序中怎么保证多线程的运行安全? 线程的安全必须满足以下方面:
(1)原子性(atomic):互斥访问,同一时刻只能有一个线程对数据进行操作。
(2)可见性(volatile):一个线程对内存的修改可以及时地被其它线程看到。
(3)有序性:一个线程观察其它线程中的指令执行顺序,由于指令重排序,该观察 结果一般杂乱无序。
48.多线程锁的升级原理是什么? 锁有四种状态从低到高:无状态锁、偏向锁、轻量锁、重量级锁状态。

49.什么是死锁? 简而言之,死锁就是两个或者两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信造成一种堵塞的一种现象,那么这种现象就是死锁。
50.怎么防止死锁?
防止死锁的四个必要条件:
(1)互斥条件:进程对所有分配的资源不允许其它进程进行访问,若其它进程访问该资源,只能等待,直到占有该资源的进度使用完成后释放该资源。
(2)请求和保持条件:进程获得一定资源之后,又对其它资源发出请求,但是该资源可能被其它进程占用,请求阻塞,但又对自己获得的资源保持不放。
(3)不可剥夺条件:是指进程已获得的资源,在未完成使用之前,不可被剥夺,只能在使用完后释放。
(4)环路等待条件:是指进程发生死锁后,若干进程之间形成一种头尾相接的循环等待资源关系。
51.ThreadLocal 是什么?有哪些使用场景?
ThreadLocal 是线程本地存储,在每个线程中都创建了一个 ThreadLocalMap 对象,每个线程可以访问自己内部 ThreadLocalMap 对象内的 value。通过这种方式,避免资源在多线程间共享。 经典的使用场景是为每个线程分配一个 JDBC 连接 Connection。这样就可以保证每个线程的都在各自的 Connection 上进行数据库的操作,不会出现 A 线程关了 B线程正在使用的 Connection;还有 Session 管理 等问题。
52.说一下 synchronized 底层实现原理?
简单的说synchronized可以保证方法或者代码块在运行时,同一时刻只有一个方法可以进入到临界区,同时还可以保证共享变量的内存可见性。 synchronized关键字可以将对象或者方法标记为同步,以实现对对象和方法的互斥访问,可以用synchronized(对象) { … }定义同步代码块,或者在声明方法时将synchronized作为方法的修饰符。
53.synchronized 和 volatile 的区别是什么?
(1)volatile本质是在告诉jvm当前变量在寄存器(工作内存)中的值是不确定的,需要从主存中读取;synchronized则是锁定当前变量,只有当前线程可以访问该变量,其他线程被阻塞住。
(2)volatile仅能使用在变量级别;synchronized则可以使用在变量、方法、和类级别的
(3)volatile仅能实现变量的修改可见性,不能保证原子性;而synchronized则可以保证变量的修改可见性和原子性
(4)volatile不会造成线程的阻塞;synchronized可能会造成线程的阻塞。
(5)volatile标记的变量不会被编译器优化;synchronized标记的变量可以被编译器优化
54.synchronized 和 Lock 有什么区别?
Lock是Java 5以后引入的新的API,和关键字synchronized相比主要相同点:Lock 能完成synchronized所实现的所有功能;主要不同点:Lock有比synchronized更精确的线程语义和更好的性能,而且不强制性的要求一定要获得锁。synchronized会自动释放锁,而Lock一定要求程序员手工释放,并且最好在finally 块中释放(这是释放外部资源的最好的地方)。
55.synchronized 和 ReentrantLock 区别是什么?
(1)synchronized 竞争锁时会一直等待;ReentrantLock 可以尝试获取锁,并得到获取结果
(2)synchronized 获取锁无法设置超时;ReentrantLock 可以设置获取锁的超时时间
(3)synchronized 无法实现公平锁;ReentrantLock 可以满足公平锁,即先等待先获取到锁
(4)synchronized 控制等待和唤醒需要结合加锁对象的 wait() 和 notify()、notifyAll();ReentrantLock 控制等待和唤醒需要结合 Condition 的 await() 和 signal()、signalAll() 方法
(5)synchronized 是 JVM 层面实现的;ReentrantLock 是 JDK 代码层面实现
(6)synchronized 在加锁代码块执行完或者出现异常,自动释放,ReentrantLock 不会自动释放锁,需要在 finally{} 代码块显示释放
56.说一下 atomic 的原理?
Atomic包中的类基本的特性就是在多线程环境下,当有多个线程同时对单个(包括基本类型及引用类型)变量进行操作时,具有排他性,即当多个线程同时对该变量的值进行更新时,仅有一个线程能成功,而未成功的线程可以向自旋锁一样,继续尝试,一直等到执行成功。
Atomic系列的类中的核心方法都会调用unsafe类中的几个本地方法。我们需要先知道一个东西就是Unsafe类,全名为:sun.misc.Unsafe,这个类包含了大量的对C代码的操作,包括很多直接内存分配以及原子操作的调用,而它之所以标记为非安全的,是告诉你这个里面大量的方法调用都会存在安全隐患,需要小心使用,否则会导致严重的后果,例如在通过unsafe分配内存的时候,如果自己指定某些区域可能会导致一些类似C++一样的指针越界到其他进程的问题。
下一期:Java最常见208道面试题_反射
微信公众号:Java先生 期待与你产生技术的火花