1.什么是线程?
线程是操作系统可能进行运算调度的最小单位,它被蕴含在过程之中,是过程中的理论运作单位。程序员能够通过它进行多处理器编程,你能够应用多线程对 运算密集型工作提速。比方,如果一个线程实现一个工作要100毫秒,那么用十个线程实现改工作只需10毫秒。Java在语言层面对多线程提供了卓越的 持,它也是一个很好的卖点。欲了解更多详细信息请点击这里。
2.线程和过程有什么区别?
线程是过程的子集,一个过程能够有很多线程,每条线程并行执行不同的工作。不同的过程应用不同的内存空间,而所有的线程共享一片雷同的内存空间。别把它和栈内存搞混,每个线程都领有独自的栈内存用来存储本地数据。
3.如何在Java中实现线程?
在语言层面有两种形式。java.lang.Thread 类的实例就是一个线程然而它须要调用java.lang.Runnable接口来执行,因为线程类自身就是调用的Runnable接口所以你能够继承 java.lang.Thread 类或者间接调用Runnable接口来重写run()办法实现线程。
4.用Runnable还是Thread?
这个问题是上题的后续,大家都晓得咱们能够通过继承Thread类或者调用Runnable接口来实现线程,问题是,那个办法更好呢?什么状况下使 用它?这个问题很容易答复,如果你晓得Java不反对类的多重继承,但容许你调用多个接口。所以如果你要继承其余类,当然是调用Runnable接口好了。
5.Thread 类中的start() 和 run() 办法有什么区别?
这个问题常常被问到,但还是能从此辨别出面试者对Java线程模型的了解水平。start()办法被用来启动新创建的线程,而且start()外部 调用了run()办法,这和间接调用run()办法的成果不一样。当你调用run()办法的时候,只会是在原来的线程中调用,没有新的线程启 动,start()办法才会启动新线程。
6.Java中Runnable和Callable有什么不同?
Runnable和Callable都代表那些要在不同的线程中执行的工作。Runnable从JDK1.0开始就有了,Callable是在 JDK1.5减少的。它们的次要区别是Callable的 call() 办法能够返回值和抛出异样,而Runnable的run()办法没有这些性能。Callable能够返回装载有计算结果的Future对象。
7.Java中CyclicBarrier 和 CountDownLatch有什么不同?
CyclicBarrier 和 CountDownLatch 都能够用来让一组线程期待其它线程。与 CyclicBarrier 不同的是,CountdownLatch 不能从新应用。
8.Java内存模型是什么?
Java内存模型规定和指引Java程序在不同的内存架构、CPU和操作系统间有确定性地行为。它在多线程的状况下尤其重要。Java内存模型对一 个线程所做的变动能被其它线程可见提供了保障,它们之间是后行产生关系。这个关系定义了一些规定让程序员在并发编程时思路更清晰。比方,后行产生关系确保了:
线程内的代码可能按先后顺序执行,这被称为程序秩序规定。
对于同一个锁,一个解锁操作肯定要产生在工夫上后产生的另一个锁定操作之前,也叫做管程锁定规定。
前一个对volatile的写操作在后一个volatile的读操作之前,也叫volatile变量规定。
一个线程内的任何操作必须在这个线程的start()调用之后,也叫作线程启动规定。
一个线程的所有操作都会在线程终止之前,线程终止规定。
一个对象的终结操作必须在这个对象结构实现之后,也叫对象终结规定。
可传递性
9.Java中的volatile 变量是什么?
volatile是一个非凡的修饰符,只有成员变量能力应用它。在Java并发程序短少同步类的状况下,多线程对成员变量的操作对其它线程是通明的。volatile变量能够保障下一个读取操作会在前一个写操作之后产生,就是上一题的volatile变量规定。
10.什么是线程平安?Vector是一个线程安全类吗?
如果你的代码所在的过程中有多个线程在同时运行,而这些线程可能会同时运行这段代码。如果每次运行后果和单线程运行的后果是一样的,而且其余的变量 的值也和预期的是一样的,就是线程平安的。一个线程平安的计数器类的同一个实例对象在被多个线程应用的状况下也不会呈现计算失误。很显然你能够将汇合类分 成两组,线程平安和非线程平安的。Vector 是用同步办法来实现线程平安的, 而和它类似的ArrayList不是线程平安的。在此我向大家举荐一个架构学习交换圈。交流学习伪鑫:1253431195(外面有大量的面试题及答案)外面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码剖析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的常识体系。还能支付收费的学习资源,目前受害良多
11.Java中什么是竞态条件? 举个例子阐明。
竞态条件会导致程序在并发状况下呈现一些bugs。多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到前面执行了, 那么整个程序就会呈现一些不确定的bugs。这种bugs很难发现而且会反复呈现,因为线程间的随机竞争。
12.Java中如何进行一个线程?
Java提供了很丰盛的API但没有为进行线程提供API。JDK 1.0原本有一些像stop(), suspend() 和 resume()的管制办法然而因为潜在的死锁威逼因而在后续的JDK版本中他们被弃用了,之后Java API的设计者就没有提供一个兼容且线程平安的办法来进行一个线程。当run() 或者 call() 办法执行完的时候线程会主动完结,如果要手动完结一个线程,你能够用volatile 布尔变量来退出run()办法的循环或者是勾销工作来中断线程。
13.Java中Semaphore是什么?
Java中的Semaphore是一种新的同步类,它是一个计数信号。从概念上讲,从概念上讲,信号量保护了一个许可汇合。如有必要,在许可可用前 会阻塞每一个 acquire(),而后再获取该许可。每个 release()增加一个许可,从而可能开释一个正在阻塞的获取者。然而,不应用理论的许可对象,Semaphore只对可用许可的号码进行计数,并采 取相应的口头。信号量经常用于多线程的代码中,比方数据库连接池。
14.如果你提交工作时,线程池队列已满。会时发会生什么?
这个问题问得很狡猾,许多程序员会认为该工作会阻塞直到线程池队列有空位。事实上如果一个工作不能被调度执行那么ThreadPoolExecutor’s submit()办法将会抛出一个RejectedExecutionException异样。
15.Java线程池中submit() 和 execute()办法有什么区别?
两个办法都能够向线程池提交工作,execute()办法的返回类型是void,它定义在Executor接口中, 而submit()办法能够返回持有计算结果的Future对象,它定义在ExecutorService接口中,它扩大了Executor接口,其它线 程池类像ThreadPoolExecutor和ScheduledThreadPoolExecutor都有这些办法。
16.什么是阻塞式办法?
阻塞式办法是指程序会始终期待该办法实现期间不做其余事件,ServerSocket的accept()办法就是始终期待客户端连贯。这里的阻塞是 指调用后果返回之前,以后线程会被挂起,直到失去后果之后才会返回。此外,还有异步和非阻塞式办法在工作实现前就返回。
17.Swing是线程平安的吗? 为什么?
你能够很必定的给出答复,Swing不是线程平安的,然而你应该解释这么答复的起因即使面试官没有问你为什么。当咱们说swing不是线程平安的常 常提到它的组件,这些组件不能在多线程中进行批改,所有对GUI组件的更新都要在AWT线程中实现,而Swing提供了同步和异步两种回调办法来进行更新。在此我向大家举荐一个架构学习交换圈。交流学习伪鑫:1253431195(外面有大量的面试题及答案)外面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码剖析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化、分布式架构等这些成为架构师必备的常识体系。还能支付收费的学习资源,目前受害良多
18.Java中invokeAndWait 和 invokeLater有什么区别?
这两个办法是Swing API 提供给Java开发者用来从以后线程而不是事件派发线程更新GUI组件用的。InvokeAndWait()同步更新GUI组件,比方一个进度条,一旦进 度更新了,进度条也要做出相应扭转。如果进度被多个线程跟踪,那么就调用invokeAndWait()办法申请事件派发线程对组件进行相应更新。而 invokeLater()办法是异步调用更新组件的。
19.Swing API中那些办法是线程平安的?
这个问题又提到了swing和线程平安,尽管组件不是线程平安的然而有一些办法是能够被多线程平安调用的,比方repaint(), revalidate()。 JTextComponent的setText()办法和JTextArea的insert() 和 append() 办法也是线程平安的。
20.如何在Java中创立Immutable对象?
这个问题看起来和多线程没什么关系, 但不变性有助于简化曾经很简单的并发程序。Immutable对象能够在没有同步的状况下共享,升高了对该对象进行并发拜访时的同步化开销。可是Java 没有@Immutable这个注解符,要创立不可变类,要实现上面几个步骤:通过构造方法初始化所有成员、对变量不要提供setter办法、将所有的成员 申明为公有的,这样就不容许间接拜访这些成员、在getter办法中,不要间接返回对象自身,而是克隆对象,并返回对象的拷贝。