Java多线程面试题

来源:互联网 发布:俊平大魔王知乎 编辑:程序博客网 时间:2024/06/04 23:28

1.线程与进程的区别是什么:

1)线程是进程的子集,一个进程可以有很多线程


2)所有的线程共享一片相同的内存空间,每个线程都拥有单独的

栈内存用来存储本地数据


3)进程是资源分配和拥有的单位,线程是处理器调度的基本单位



4)二者均可并发执行


2.Thread 类中的 start () 和 run () 方法有什么区别?


当你调用 run ()方法的时候,只会是在原来的线程中调用,没有新


的线程启动,start ()方法才会启动新线程



3.Java 中 Runnable 和 Callable 有什么不同?


它们的主要区别是 Callable 的 call () 方法可以返回值和抛出异


常,而 Runnable 的 run ()方法没有这些功能。Callable 可以返


回装载有计算结果的 Future 对象。


4.(JMMJava 内存模型是什么?


http://blog.csdn.net/zgmzyr/article/details/8798568


线程A与线程B之间如要通信的话,必须要经历下面2个步骤

  1. 首先,线程A把本地内存A中更新过的共享变量刷新到主内存中去。
  2. 然后,线程B到主内存中去读取线程A之前已更新过的共享变量。
JMM通过控制主内存与每个线程的本地内存之间的交互,来为java程序员提供内存可见性保证。

5.java中的Java 中的 volatile 变量是什么?

 Volatile保证可见性Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。而且,当成员变量发生变化时,强迫线程将变化值回写到共享内存。这样在任何时刻,两个不同的线程总是看到某个成员变量的同一个值。

6.什么是线程安全?


如果每次运行结果和单线程运行的结果是一样的,而且其他的变量的值也和预期的是一样的,就是线程安全的。


Vector 是用同步方法来实现线程安全的, 而和它相似的 ArrayList 不是线程安全的。


7. 如何在两个线程间共享数据?


(涉及到在两个线程间共享对象)用 wait 和 notify 方法实现了生产者消费者模型


notify ()方法不能唤醒某个具体的线程,所以只有一个线程在等待


的时候它才有用武之地。而 notifyAll ()唤醒所有线程并允许他们


争夺锁确保了至少有一个线程能继续运行


8. Java 中的同步集合与并发集合有什么区别?


Java1.5 之前程序员们只有同步集合来用且在多线程并发的时候会


导致争用,阻碍了系统的扩展性。Java5 介绍了并发集合像 


ConcurrentHashMap,不仅提供线程安全还用锁分离和内部分区


等现代技术提高了可扩展性


9. Java 中堆和栈有什么不同?


线程都有自己的栈内存,用于存储本地变量,方法参数和栈调用,



而堆是所有线程共享的一片公用内存区域



10.什么是线程池? 为什么要使用它?



创建线程要花费昂贵的资源和时间,如果任务来了才创建线程那

么响应时间会变长,而且一个进程能创建的线程数有限。为了避

免这些问题,在程序启动的时候就创建若干线程来响应处理,它

们被称为线程池,里面的线程叫工作线程



11.如何写代码来解决生产者消费者问题?


比较低级的办法是用 wait 和 notify 来解决这个问题,比较赞的办

法是用 Semaphore 或者 BlockingQueue 来实现生产者消费者模



12.Java 中 synchronized 和 ReentrantLock 有什么不同?

Java 在过去很长一段时间只能通过 synchronized 关键字来实现

互斥,它有一些缺点。比如你不能扩展锁之外的方法或者块边

界,尝试获取锁时不能中途取消等。Java 5 通过 Lock 接口提供

了更复杂的控制


13. 有三个线程 T1,T2,T3,怎么确保它们按顺序执行?

可以用线程类的 join ()方法在一个线程中启动另一个线程,另外

一个线程完成该线程继续执行。


14.Thread 类中的 yield 方法有什么作用?

Yield 方法可以暂停当前正在执行的线程对象,让其它有相同优先

级的线程执行。它是一个静态方法而且只保证当前线程放弃 CPU

占用而不能保证使其它线程一定能占用 CPU,执行 yield ()的线

程有可能在进入到暂停状态后马上又被执行


15.Java 中 ConcurrentHashMap 的并发度是什么?


oncurrentHashMap 把实际 map 划分成若干部分来实现它的可

扩展性和线程安全。这种划分是使用并发度获得的,它是 

ConcurrentHashMap 类构造函数的一个可选参数,默认值为 

16,这样在多线程情况下就能避免争用。



16. Java 多线程中调用 wait () 和 sleep ()方法有什么不同?

wait ()方法用于线程间通信,如果等待条件为真且其它线程被唤

醒时它会释放锁,而 sleep ()方法仅仅释放 CPU 资源或者让当前

线程停止执行一段时间,但不会释放锁。




17.虽然你可以使用 System.gc ()来进行垃圾回收,但是不保证能成功


18.单例模式:


欢双检锁JVM 的类加载和静态变量初始化特征来创建 Singleton 

实例


第一种(懒汉,线程不安全):

 

Java代码  收藏代码
  1. public class Singleton {  
  2.     private static Singleton instance;  
  3.     private Singleton (){}  
  4.   
  5.     public static Singleton getInstance() {  
  6.     if (instance == null) {  
  7.         instance = new Singleton();  
  8.     }  
  9.     return instance;  
  10.     }  
  11. }  


第二种(懒汉,线程安全):

 

Java代码  收藏代码
  1. public class Singleton {  
  2.     private static Singleton instance;  
  3.     private Singleton (){}  
  4.     public static synchronized Singleton getInstance() {  
  5.     if (instance == null) {  
  6.         instance = new Singleton();  
  7.     }  
  8.     return instance;  
  9.     }  
  10. }  

第四种(饿汉,变种):

 

Java代码  收藏代码
  1. public class Singleton {  
  2.     private Singleton instance = null;  
  3.     static {  
  4.     instance = new Singleton();  
  5.     }  
  6.     private Singleton (){}  
  7.     public static Singleton getInstance() {  
  8.     return this.instance;  
  9.     }  
  10. }  
 

第五种(静态内部类):

 

Java代码  收藏代码
  1. public class Singleton {  
  2.     private static class SingletonHolder {  
  3.     private static final Singleton INSTANCE = new Singleton();  
  4.     }  
  5.     private Singleton (){}  
  6.     public static final Singleton getInstance() {  
  7.     return SingletonHolder.INSTANCE;  
  8.     }  
  9. }  

第六种(枚举):

 

Java代码  收藏代码
  1. public enum Singleton {  
  2.     INSTANCE;  
  3.     public void whateverMethod() {  
  4.     }  
  5. }  

 

 这种方式是Effective Java作者Josh Bloch 提倡的方式,它不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,可谓是很坚强的壁垒啊,不过,个人认为由于1.5中才加入enum特性,用这种方式写不免让人感觉生疏,在实际工作中,我也很少看见有人这么写过。


第七种(双重校验锁):

Java代码  收藏代码
  1. public class Singleton {  
  2.     private volatile static Singleton singleton;  
  3.     private Singleton (){}  
  4.     public static Singleton getSingleton() {  
  5.     if (singleton == null) {  
  6.         synchronized (Singleton.class) {  
  7.         if (singleton == null) {  
  8.             singleton = new Singleton();  
  9.         }  
  10.         }  
  11.     }  
  12.     return singleton;  
  13.     }  
  14. }  


0 0
原创粉丝点击