51、Collection和Collections的区别?
答:Collection是最基本的集合接口,其子接口有List和Set,提供了对集合对象进行基本操作的通用接口方法;Collections是集合类的一个工具类,提供了一系列静态方法对集合中元素进行排序、搜索和线程安全等操作。
52、List、Map、Set三个接口存取元素时,各有什么特点?
答:List存放元素是有序的且可以重复,Set存放元素是无序的且不可重复,Map中的元素是以键值对key-value的形式存放的,键key无序的不可重复,值value可以重复;List取出元素可以用for循环,foreach循环和Iterator迭代器迭代,Set可以用foreach循环和Iterator迭代器迭代,Map取出元素要把key转换为Set存储,再进行Iterator迭代器迭代,即用map.get(key)来获取value,也可以转换为entry对象用迭代器迭代。
53、TreeMap和TreeSet在排序时如何比较元素?Collections工具类中的sort()方法如何比较元素?
答:TreeSet要求存放的对象所属的类必须实现Comparable接口,该接口提供了比较元素的compareTo()方法,当插入元素时会回调该方法比较元素的大小。TreeMap要求存放的键值对映射的键必须实现Comparable接口从而根据键对元素进行排序。Collections工具类的sort方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现Comparable接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator接口的子类型(需要重写compare方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java中对函数式编程的支持)。
54、Thread类的sleep()方法和对象的wait()方法都可以让线程暂停执行,它们有什么区别?
答:sleep() 方法是线程类(Thread)的静态方法,让调用线程进入睡眠状态,让出执行机会给其他线程,等到休眠时间结束后,线程进入就绪状态和其他线程一起竞争cpu的执行时间。
因为sleep() 是static静态的方法,他不能改变对象的机锁,当一个synchronized块中调用了sleep() 方法,线程虽然进入休眠,但是对象的机锁没有被释放,其他线程依然无法访问这个对象。wait()是Object类的方法,调用对象的wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify()方法(或notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。
55、线程的sleep()方法和yield()方法有什么区别?
答:① sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
② 线程执行sleep()方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
③ sleep()方法声明抛出InterruptedException,而yield()方法没有声明任何异常;
④ sleep()方法比yield()方法(跟操作系统CPU调度相关)具有更好的可移植性。
56、当一个线程进入一个对象的synchronized方法A之后,其它线程是否可进入此对象的synchronized方法B?
答:1.其他方法前是否加了synchronized关键字,如果没加,则能,但是方法B前面有synchronized修饰了,故还不能判断,继续往下看。
2.如果方法A内部调用了wait(),则可以进入synchronized方法B;如果其内部没有调用wait,则不能。
3.如果方法B是static,它用的同步锁是当前类的字节码,与非静态的方法不能同步,因为非静态的方法用的是this。
57、请说出与线程同步以及线程调度相关的方法。
答:wait():使一个线程处于等待(阻塞)状态,并且释放持有锁的对象;
sleep():使一个正在运行的线程处于睡眠状态,是静态方法,调用此方法要处理InterruptedException异常;
notify():唤醒一个处于等待状态的线程,但是不能确切地唤醒某一个处于等待状态的线程,而是由JVM确定,而且与优先级无关;
NotifyAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态。
58、编写多线程程序有几种实现方式?
答:有四种方式。
1.继承Thread类,重写run方法,无返回值。
2.实现Runnable接口,重写run方法,无返回值,实现Runnable接口的实现类的实例对象作为Thread构造函数的target。
3.通过Callable和Future Task来创建线程,要实现call()方法,其返回值为Object。
4.通过线程池创建线程。
59、synchronized关键字的用法?
答:synchronized关键字可以用来修饰方法、一个代码块、静态方法和类。
- 修饰方法:
- 修饰代码块:
3.修饰静态方法:
4.修饰类:
60、举例说明同步和异步。
答:如果系统中存在临界资源(资源数量少于竞争资源的线程数量的资源),例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就必须进行同步存取(数据库操作中的排他锁就是最好的例子)。
当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。
事实上,所谓的同步就是指阻塞式操作,而异步就是非阻塞式操作。
以通讯为例:
同步:发送一个请求,等待返回,然后再发送下一个请求
异步:发送一个请求,不等待返回,随时可以再发送下一个请求
并发:同时发送多个请求