转载自 JAVA面试常考系列二
题目一
解释一下线程和进程
进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,进程是系统进行资源分配和调度的一个独立单位。
线程是进程的一个实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位.线程自己基本上不拥有系统资源,只拥有一点在运行中必不可少的资源,如程序计数器,一组寄存器和栈,但是线程可以与同一个进程种其它的线程共享进程的全部资源。
进程与线程有什么区别?
1、线程的划分尺度小于进程,使得多线程程序的并发性高。
2、进程在执行过程中拥有独立的内存单元,而多个线程共享内存,从而极大地提高了程序的运行效率。
3、每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行,必须依存在应用程序中,由应用程序提供多个线程执行控制。
4、一个进程崩溃后,在保护模式下不会对其它进程产生影响。线程只是一个进程的不同执行路径,线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉。
创建线程有几种不同的方式?
线程的创建方式有下面三种:
1、继承Thread类(真正意义上的线程类),是Runnable接口的实现。
2、实现Runnable接口,并重写里面的run方法。
3、使用Executor框架创建线程池。
其中实现Runnable接口这种方式更受欢迎,因为这不需要继承Thread类。在应用设计中已经继承了别的对象的情况下,这需要多继承(而Java不支持多继承),只能实现接口。同时,线程池也是非常高效的,很容易实现和使用。
线程的几种可用状态分别是什么?
1.新建(new)
新创建了一个线程对象。
2.可运行(runnable)
线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu的使用权。
3.运行(running)
可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。
4.阻塞(block)
阻塞状态是指线程因为某种原因放弃了cpu使用权,也即让出了cpu timeslice,暂时停止运行。直到线程进入可运行(runnable)状态,才有 机会再次获得cpu timeslice转到运行(running)状态。阻塞的情况分三种:
a、等待阻塞:运行(running)的线程执行o.wait()方法,JVM会把该线程放入等待队列(waitting queue)中。
b、同步阻塞:运行(running)的线程在获取对象的同步锁时,若该同步锁 被别的线程占用,则JVM会把该线程放入锁池(lock pool)中。
c、其他阻塞: 运行(running)的线程执行Thread.sleep(long ms)或t.join()方法或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时或者I/O处理完毕时,线程重新转入可运行(runnable)状态。
5.死亡(dead)
线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。
同步方法和同步代码块的区别是什么?
定义
同步方法是指有synchronized关键字修饰的方法。由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
同步代码块是指有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。
区别
1、同步方法默认用this或者当前类class对象作为锁;
2、同步方法作用于整个方法,同步代码块作用范围更小,作用于整个代码块。
3、同步方法使用关键字synchronized修饰方法,而同步代码块主要是修饰需要进行同步的代码,用synchronized(object){代码内容}进行修饰;
在监视器(Monitor)内部,线程同步是如何实现的?
监视器和锁在Java虚拟机中是一块使用的。监视器监视一块同步代码块,确保一次只有一个线程执行同步代码块。每一个监视器都和一个对象引用相关联。线程在获取锁之前不允许执行同步代码。
什么是死锁(deadlock),产生的条件是什么?
死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象。
死锁的发生必须具备以下四个必要条件。
1.互斥
互斥条件是指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只由一个进程占用。如果此时还有其它进程请求资源,则请求者只能等待,直至占有资源的进程用毕释放。
2.请求和保持
请求和保持条件是指进程已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它进程占有,此时请求进程阻塞,但又对自己已获得的其它资源保持不放。
3.不剥夺
不剥夺条件是指进程已获得的资源,在未使用完之前,不能被剥夺,只能在使用完时由自己释放。
4.环路
环路等待条件是指在发生死锁时,必然存在一个进程——资源的环形链,即进程集合{P0,P1,P2,···,Pn}中的P0正在等待一个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。
如何确保多个线程可以访问多个资源同时又不导致死锁?
如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。所以为了确保多个线程访问多个资源同时又不导致死锁,我们可以指定获取锁的顺序,并强制线程按照指定的顺序获取锁。
Java集合类框架的基本接口有哪些?
Java集合类提供了一套设计良好的支持对一组对象进行操作的接口和类。Java集合类里面最基本的接口有:
Collection:代表一组对象,每一个对象都是它的子元素。
Set:不包含重复元素的Collection。
List:有顺序的collection,并且可以包含重复元素。
Map:可以把键(key)映射到值(value)的对象,键不能重复。
集合类接口指定了一组叫做元素的对象。集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序。有的集合类允许重复的键,有些不允许。
为什么集合类没有实现Cloneable和Serializable接口?
集合类接口指定了一组叫做元素的对象。集合类接口的每一种具体的实现类都可以选择以它自己的方式对元素进行保存和排序。有的集合类允许重复的键,有些不允许。