35.并行和并发有什么区别?
并发是多个事件在同一时间段执行,而并行是多个事件在同一时间点执行。
36.线程和进程的区别?
进程:是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竞争计算机系统资源的基本单位。
线程:是进程的一个执行单元,是进程内部调度实体。比进程更小的独立运行的基本单位。线程也被称为轻量级进程。
一个程序至少一个进程,一个进程至少一个线程。
进程线程的区别:
- 地址空间:同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间。
- 资源拥有:同一进程内的线程共享本进程的资源如内存、I/O、cpu等,但是进程之间的资源是独立的。
一个进程崩溃后,在保护模式下不会对其他进程产生影响,但是一个线程崩溃整个进程都死掉。所以多进程要比多线程健壮。
进程切换时,消耗的资源大,效率高。所以涉及到频繁的切换时,使用线程要好于进程。同样如果要求同时进行并且又要共享某些变量的并发操作,只能用线程不能用进程
执行过程:每个独立的进程程有一个程序运行的入口、顺序执行序列和程序入口。但是线程不能独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。线程是处理器调度的基本单位,但是进程不是。两者均可并发执行。
优缺点:
线程执行开销小,但是不利于资源的管理和保护。线程适合在SMP机器(双CPU系统)上运行。
进程执行开销大,但是能够很好的进行资源管理和保护。进程可以跨机器前移。
37.守护线程是什么?
守护线程(即daemon thread),是个服务线程,准确地来说就是服务其他的线程,这是它的作用——而其他的线程只有一种,那就是用户线程。所以java里线程分2种,
1、守护线程,比如垃圾回收线程,就是最典型的守护线程。
2、用户线程,就是应用程序里的自定义线程。
守护线程
1、守护线程,专门用于服务其他的线程,如果其他的线程(即用户自定义线程)都执行完毕,连main线程也执行完毕,那么jvm就会退出(即停止运行)——此时,连jvm都停止运行了,守护线程当然也就停止执行了。
2、再换一种说法,如果有用户自定义线程存在的话,jvm就不会退出——此时,守护线程也不能退出,也就是它还要运行,干嘛呢,就是为了执行垃圾回收的任务啊。
38.创建线程有哪几种方式?
编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互。一般有四种方法,Thread,Runnable,Callable,使用Executor框架来创建线程池。
Runnable和Callable的区别是,
(1)Callable规定的方法是call(),Runnable规定的方法是run().
(2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值得
(3)call方法可以抛出异常,run方法不可以
(4)运行Callable任务可以拿到一个Future对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过Future对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果。
39.说一下 runnable 和 callable 有什么区别?
| 方 法 名 | ExecutorService的执行方法 | ExecutorService.submit()返回值 | 返回的Future调用get()方法 | 线程体 | 取消执行 |
|---|---|---|---|---|---|
| Runnable | execute和submit | Future | null | run() | 不能 |
| Callable | 只能是submit | Future | Future定义的泛型T | call() | Future.cancel能取消执行 |
40.线程有哪些状态?
41.sleep() 和 wait() 有什么区别?
42.notify()和 notifyAll()有什么区别?
notify():
唤醒一个处于等待状态的线程,
注意的是在调用此方法的时候,
并不能确切的唤醒某一个等待状态的线程,
而是由JVM确定唤醒哪个线程,而且不是按优先级。
notifyAll():
唤醒所有处入等待状态的线程;
并可以理解为把他们排进一个队列;
只不过只有头部的线程获得了锁,才能运行;
注意!!并不是给所有唤醒线程一个对象的锁,而是让它们竞争,
当其中一个线程运行完就开始运行下一个已经被唤醒的线程,因为锁已经转移了。
(这个时候是否运行已经不是因为等待状态,而是处于runnning队列中)
43.线程的 run()和 start()有什么区别?
44.创建线程池有哪几种方式?
newCachedThreadPool
newFixedThreadPool
newSingleThreadExecutor
newScheduleThreadPool
45.线程池都有哪些状态?
Running、ShutDown、Stop、Tidying、Terminated
46.线程池中 submit()和 execute()方法有什么区别?
1)接收的参数不一样
2)submit有返回值,而execute没有
用到返回值的例子,比如说我有很多个做validation的task,我希望所有的task执行完,然后每个task告诉我它的执行结果,是成功还是失败,如果是失败,原因是什么。
然后我就可以把所有失败的原因综合起来发给调用者。
个人觉得cancel execution这个用处不大,很少有需要去取消执行的。
而最大的用处应该是第二点。
3)submit方便Exception处理
意思就是如果你在你的task里会抛出checked或者unchecked exception,
而你又希望外面的调用者能够感知这些exception并做出及时的处理,那么就需要用到submit,通过捕获Future.get抛出的异常。
47.在 java 程序中怎么保证多线程的运行安全?
原子性(Synchronized, Lock)
有序性(Volatile,Synchronized, Lock)
可见性(Volatile,Synchronized,Lock)
当然死锁的产生是必须要满足一些特定条件的:
1.互斥条件:进程对于所分配到的资源具有排它性,即一个资源只能被一个进程占用,直到被该进程释放
2.请求和保持条件:一个进程因请求被占用资源而发生阻塞时,对已获得的资源保持不放。
3.不剥夺条件:任何一个资源在没被该进程释放之前,任何其他进程都无法对他剥夺占用
4.循环等待条件:当发生死锁时,所等待的进程必定会形成一个环路(类似于死循环),造成永久阻塞。
48.多线程锁的升级原理是什么?
49.什么是死锁?
线程死锁是指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。当线程进入对象的synchronized代码块时,便占有了资源,直到它退出该代码块或者调用wait方法,才释放资源,在此期间,其他线程将不能进入该代码块。当线程互相持有对方所需要的资源时,会互相等待对方释放资源,如果线程都不主动释放所占有的资源,将产生死锁
50.怎么防止死锁?
如果能确保所有的线程都是按照相同的顺序获得锁,那么死锁就不会发生
一个可以避免死锁的方法是在尝试获取锁的时候加一个超时时间,这也就意味着在尝试获取锁的过程中若超过了这个时限该线程则放弃对该锁请求
死锁检测是一个更好的死锁预防机制,它主要是针对那些不可能实现按序加锁并且锁超时也不可行的场景。
51.ThreadLocal 是什么?有哪些使用场景?
52.说一下 synchronized 底层实现原理?
53.synchronized 和 volatile 的区别是什么?
1)volatile本质是告诉JVM当前变量在寄存器中的值是不确定的,需要从主存中读取。synchronized则是锁定当前变量,只有当前线程可以访问该变量,其它线程被阻塞。
2)volatile仅能使用在变量级别,synchronized则可以使用在变量、方法。
3)volatile仅能实现变量修改的可见性,而synchronized则可以保证变量修改的可见性和原子性。《
4)volatile不会造成线程阻塞,synchronized会造成线程阻塞。
5)使用volatile而不是synchronized的唯一安全情况是类中只有一个可变的域。
当一个域的值依赖于它之前的值时,volatile就无法工作了,如n=n+1,n++等。如果某个域的值受到其他域的值的限制,那么 volatile也无法工作,如Range类的lower和upper边界,必须遵循lower<=upper的限制。使用volatile而不是synchronized的唯一安全的情况是类中只有一个可变的域。
54.synchronized 和 Lock 有什么区别?
1)用法不一样。synchronized既可以加在方法上,也可以加载特定的代码块上,括号中表示需要锁的对象。而Lock需要显示地指定起始位置和终止位置。synchronzied是托管给jvm执行的,Lock锁定是通过代码实现的。
2)在性能上来说,如果竞争资源不激烈,两者的性能是差不多的,而当竞争资源非常激烈时(即有大量线程同时竞争),此时Lock的性能要远远优于synchronized。所以说,在具体使用时要根据适当情况选择。
3)锁的机制不一样。synchronized获得锁和释放的方式都是在块结构中,而且是自动释放锁。而Lock则需要开发人员手动去释放,并且必须在finally块中释放,否则会引起死锁问题的发生。
4)Lock是一个接口,而synchronized是Java中的关键字,synchronized是内置的语言实现;
5)synchronized在发生异常时,会自动释放线程占有的锁,因此不会导致死锁现象发生;而Lock在发生异常时,如果没有主动通过unLock()去释放锁,则很可能造成死锁现象,因此使用Lock时需要在finally块中释放锁;
6)Lock可以让等待锁的线程响应中断,而synchronized却不行,使用synchronized时,等待的线程会一直等待下去,不能够响应中断;通过Lock可以知道有没有成功获取锁,而synchronized却无法办到。Lock可以提高多个线程进行读操作的效率
55.synchronized 和 ReentrantLock 区别是什么?
56.说一下 atomic 的原理?