Java多线程面试问题集锦

若是你即将去一家从事大型系统研发的公司进行Java面试,不可避免的会有多线程相关的问题。下面是一些针对初学者或者新手的问题,若是你已经具有良好的基础,那么你能够跳过本文,直接尝试针对进阶水平的Java多线程编程问题及解答。html

关联连接: Java multi-threading-1 | Java multi-threading-2java

问题:进程和线程的区别
解答:一个进程对应一个程序的执行,而一个线程则是进程执行过程当中的一个单独的执行序列,一个进程能够包含多个线程。线程有时候也被称为轻量级进程.mysql

一个Java虚拟机的实例运行在一个单独的进程中,不一样的线程共享Java虚拟机进程所属的堆内存。这也是为何不一样的线程能够访问同一个对象。线程彼此共享堆内存并保有他们本身独自的栈空间。这也是为何当一个线程调用一个方法时,他的局部变量能够保证线程安全。但堆内存并非线程安全的,必须经过显示的声明同步来确保线程安全。面试

问题:列举几种不一样的建立线程的方法.
解答:能够经过以下几种方式:
•  继承Thread 类
•  实现Runnable 接口
•  使用Executor framework (这会建立一个线程池)sql

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Counter extends Thread {
 
     //method where the thread execution will start
     public void run(){
         //logic to execute in a thread   
     }
 
     //let’s see how to start the threads
     public static void main(String[] args){
        Thread t1 = new Counter();
        Thread t2 = new Counter();
        t1.start();  //start the first thread. This calls the run() method.
        t2.start(); //this starts the 2nd thread. This calls the run() method. 
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Counter extends Base implements Runnable{
 
     //method where the thread execution will start
     public void run(){
         //logic to execute in a thread   
     }
 
     //let us see how to start the threads
     public static void main(String[] args){
          Thread t1 = new Thread( new Counter());
          Thread t2 = new Thread( new Counter());
          t1.start();  //start the first thread. This calls the run() method.
          t2.start();  //this starts the 2nd thread. This calls the run() method. 
     }
}

经过线程池来建立更有效率。
相关连接: learn why and how to create pool of  threads using the executor framework数据库

问题:推荐经过哪一种方式建立线程,为何?
解答:最好使用Runnable接口,这样你的类就没必要继承Thread类,否则当你须要多重继承的时候,你将束手无策(咱们都知道Java中的类只能继承自一个类,但能够同时实现多个接口)。在上面的例子中,由于咱们要继承Base类,因此实现Runnable接口成了显而易见的选择。同时你也要注意到在不一样的例子中,线程是如何启动的。按照面向对象的方法论,你应该只在但愿改变父类的行为的时候才去继承他。经过实现Runnable接口来代替继承Thread类能够告诉使用者Counter是Base类型的一个对象,并会做为线程执行。编程

问题:简要的说明一下高级线程状态.
解答:下图说明了线程的各类状态.安全

 

• 可执行(Runnable):当调用start()方法后,一个线程变为可执行状态,可是并不意味着他会马上开始真正地执行。而是被放入线程池,由线程调度器根据线程优先级决定什么时候挂起执行。多线程

1
2
MyThread aThread = new MyThread();
aThread.start();                   //becomes runnable

• 执行中(Running):处理器已经在执行线程的代码。他会一直运行直到被阻断,或者经过静态方法Thread.yield()自行放弃执行的机会,考虑到场景切换所带来的开销,yield()方法不该该被常常调用。
• 等待中(Waiting):线程因为等待I/O等外部进程的处理结果而处于被阻断的状态,调用currObject.wait( )方法会使得当前线程进入等待状态,直到其它线程调用currObject.notify() 或者currObject.notifyAll() 。
• 睡眠中(Sleeping):重载方法Thread.sleep(milliseconds),Thread.sleep(milliseconds, nanoseconds)能够迫使Java线程进入睡眠状态(挂起)。
• 因为I/O阻塞(Blocked on I/O):当I/O条件发生变化时(例如读取了几个字节的数据)会迁移到可执行状态。
• 因为同步阻塞中(Blocked on synchronization): 当获取锁以后会进入执行中状态。性能

Thread.State 枚举类型包含了Java虚拟机支持的所有的线程状态类型,下面几点Java的线程宗旨确保了这些线程状态成为可能。
• 对象能够被任何线程共享和修改。
• 线程调度器的抢占性特性,使得线程能够随时在/不在多核处理之间切换处理器内核,这意味着方法能够在执行的过程当中切换状态。不然方法中的死循环将永远阻塞CPU,而且使得不一样线程的其余方法始终得不到执行。
• 为了防止线程安全问题,那些脆弱的方法或者代码块能够被锁定。这使得线程能够处于被锁定或者加锁请求处理中两种状态。
• 线程在处理I/O资源(如Sockets,文件句柄,数据库链接等)时会进入等待状态,
• 处于I/O读写中的线程不能被切换,所以他们或者以成功/失败的结果正常完成处理,或者其它线程关闭了相应的资源,迫使他进入死亡或者完成的状态。这也是为何一个合理的超时时间能够避免线程因为I/O处理而被永远阻塞,从而致使严重的性能问题。
• 线程能够进入睡眠状态,以使得其余处于等待状态的线程有机会执行。

问题:yield和sleeping有何区别,sleep()和wait()有何区别?
解答:当一个任务调用了yield()方法,它将从执行中状态转变为可执行。而当一个任务调用了sleep(),则将从执行中状态转变为等待中/睡眠中状态。
方法wait(1000)使得当前线程睡眠1秒钟,但调用notify() 或者notifyAll()会随时唤醒线程。而sleep(1000)则会致使当前线程休眠1秒钟。

问题:为何为了线程安全而锁定一个方法或者一个代码块称为“同步”而不是“锁定”或者“被锁定”
解答:当某个方法或者代码块被声明为”synchronized”后,保存数据的内存空间(例如堆内存)将保持被同步状态。
这意味着:当一个线程获取锁而且执行到已被声明为synchronized的方法或者代码块时,该线程首先从主堆内存空间中读取该锁定对象的全部变化,以确保其在开始执行以前拥有最新的信息。在synchronized部分执行完毕,线程准备释放锁的时候,全部针对被锁定对象的修改都将为写入主堆内存中。这样其余线程在请求锁的时候就能够获取最新的信息。

问题:线程如何进行的同步处理?你能够列举出那些同步级别?同步方法和代码块如何区别?
解答:在Java语言中,每一个对象都有一个锁,一个线程能够经过关键字synchronized来申请获取某个对象的锁,关键字synchronized能够被用于方法(粗粒度锁,对性能影响较大)或代码块(细粒度锁)级别。锁定方法每每不是一个很好的选择,取而代之的咱们应该只锁定那些访问共享资源的代码块,由于每个对象都有一个锁,因此能够经过建立虚拟对象来实现代码块级别的同步,方法块级别的锁比锁定整个方法更有效。

 

Java虚拟机灵活的使用锁和监视器,一个监视器整体来讲就是一个守卫者,他负责确保只有一个线程会在同一时间执行被同步的代码。每一个监视器对应一个对象的引用,在线程执行代码块的第一条指令以前,他必须持有该引用对象的锁,不然他将没法执行这段代码。一旦他得到锁,该线程就能够进入这段受到保护的代码。当线程不论以何种方式退出代码块时,他都将释放关联对象的锁。对于静态方法,须要请求类级别的锁。

相关文章
相关标签/搜索