76、Set 里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

答:Set 里的元素是不能重复的,用equals ()方法来区分重复与否。覆盖equals()方法用来判断对象的内容是否相同,而”==”判断地址是否相等,用来决定引用值是否指向同一对象。

77、用程序给出随便大小的10 个数,序号为1-10,按从小到大顺序输出,并输出相应的序号

答:代码如下:
package test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public class RandomSort {
public static void printRandomBySort() {
Random random = new Random(); // 创建随机数生成器
List list = new ArrayList();
// 生成10 个随机数,并放在集合list 中
for (int i = 0; i < 10; i++) {
list.add(random.nextInt(1000));
}
Collections.sort(list); // 对集合中的元素进行排序
Iterator it = list.iterator();
int count = 0;
while (it.hasNext()) { // 顺序输出排序后集合中的元素
System.out.println(++count + ": " + it.next());
}
}
public static void main(String[] args) {
printRandomBySort();
}
}

78、用JAVA 实现一种排序,JAVA 类实现序列化的方法? 在COLLECTION 框架中,实现比较要实现什么样的接口?

答:用插入法进行排序代码如下:
package test;
import java.util.*;
class InsertSort {
ArrayList al;
public InsertSort(int num,int mod) {
al = new ArrayList(num);
Random rand = new Random();
System.out.println("The ArrayList Sort Before:");
for (int i=0;i<num ;i++ ){
al.add(new Integer(Math.abs(rand.nextInt()) % mod +
1));
System.out.println("al["+i+"]="+al.get(i));
}
}
public void SortIt(){
tempInt;
int MaxSize=1;
for(int i=1;i<al.size();i++){
tempInt = (Integer)al.remove(i);
if(tempInt.intValue() >=
((Integer)al.get(MaxSize-1)).intValue()){
al.add(MaxSize,tempInt);
MaxSize++;
System.out.println(al.toString());
}else{
for (int j=0;j<MaxSize ;j++ ){
if (((Integer)al.get(j)).intValue()
=tempInt.intValue()){
al.add(j,tempInt);
MaxSize++;
System.out.println(al.toString());
break;
}
}
}
}
System.out.println("The ArrayList Sort After:");
for(int i=0;i<al.size();i++){
System.out.println("al["+i+"]="+al.get(i));
}
}
}
JAVA 类实现序例化的方法是实现java.io.Serializable 接口;Collection 框架中实现比较要实现Comparable 接口和Comparator 接口。

79、sleep() 和wait() 有什么区别?

答:sleep 是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep 不会释放对象锁。wait 是Object 类的方法,对此对象调用wait 方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify 方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。

80、当一个线程进入一个对象的一个synchronized 方法后,其它线程是否可进入此对象的其它方法

答:其它线程只能访问该对象的其它非同步方法,同步方法则不能进入。

81、请说出你所知道的线程同步的方法

答:wait():使一个线程处于等待状态,并且释放所持有的对象的lock;sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉InterruptedException 异常;notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由JVM 确定唤醒哪个线程,而且不是按优先级;
notityAll():唤醒所有处入等待状态的线程,注意并不是给所有唤醒线程一个对象的锁,而是让它们竞争。

82、多线程有几种实现方法,都是什么?同步有几种实现方法,都是什么?

答:1、继承Thread类实现多线程
2、实现Runnable接口方式实现多线程
3、使用ExecutorService、Callable、Future实现有返回结果的多线程,分别是synchronized,wait 与notify。

83、同步和异步有何异同,在什么情况下分别使用他们?

答:如果数据将在线程间共享。例如正在写的数据以后可能被另一个线程读到,或者正在读的数据可能已经被另一个线程写过了,那么这些数据就是共享数据,必须进行同步存取。当应用程序在对象上调用了一个需要花费很长时间来执行的方法,并且不希望让程序等待方法的返回时,就应该使用异步编程,在很多情况下采用异步途径往往更有效率。

84、启动一个线程是用run()还是start()?

答:启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM 调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。

85、线程的基本概念、线程的基本状态以及状态之间的关系

答:线程指在程序执行过程中,能够执行程序代码的一个执行单位,每个程序至少都有一个线程,也就是程序本身;Java 中的线程有四种状态分别是:运行、就绪、挂起、结束。

86、简述synchronized 和java.util.concurrent.locks.Lock 的异同?

答:主要相同点:Lock 能完成synchronized 所实现的所有功能;主要不同点:Lock 有比synchronized 更精确的线程语义和更好的性能。synchronized 会自动释放锁,而Lock 一定要求程序员手工释放,并且必须在finally 从句中释放。

87、java 中有几种方法可以实现一个线程?用什么关键字修饰同步方法?stop()和suspend()方法为何不推荐使用?

答:有两种实现方法,分别是继承Thread 类与实现Runnable 接口;用synchronized 关键字修饰同步方法;反对使用stop(),是因为它不安全。它会解除由线程获取的所有锁定,而且如果对象处于一种不连贯状态,那么其他线程能在那种状态下检查和修改它们。结果很难检查出真正的问题所在;suspend()方法容易发生死锁。调用suspend()的时候,目标线程会停下来,但却仍然持有在这之前获得的锁定。此时,其他任何线程都不能访问锁定的资源,除非被“挂起”的线程恢复运行。对任何线程来说,如果它们想恢复目标线程,同时又试图使用任何一个锁定的资源,就会造成死锁。故不应该使用suspend(),而应在自己的Thread 类中置入一个标志,指出线程应该活动还是挂起。若标志指出线程应该挂起,便用wait()命其进入等待状态。若标志指出线程应当恢复,则用一个notify()重新启动线程。

88、一个线程运行时发生异常会怎样

如果异常没有被捕获该线程将会停止执行。Thread.UncaughtExceptionHandler是用于处理未捕获异常造成线程突然中断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候JVM会使用Thread.getUncaughtExceptionHandler()来查询线程的UncaughtExceptionHandler并将线程和异常作为参数传递给handler的uncaughtException()方法进行处理。

89、线程yield()方法有什么用

Yield方法可以暂停当前正在执行的线程对象,让其它有相同优先级的线程执行。它是一个静态方法而且只保证当前线程放弃CPU占用而不能保证使其它线程一定能占用CPU,执行yield()的线程有可能在进入到暂停状态后马上又被执行

90、什么是重入锁

所谓重入锁,指的是以线程为单位,当一个线程获取对象锁之后,这个线程可以再次获取本对象上的锁,而其他的线程是不可以的。

91、线程数过多会造成什么异常?

线程过多会造成栈溢出,也有可能会造成堆异常

92、什么是CAS算法?在多线程中有哪些应用

CAS,全称为Compare and Swap,即比较-替换。假设有三个操作数:内存值V、旧的预期值A、要修改的值B,当且仅当预期值A和内存值V相同时,才会将内存值修改为B并返回true,否则什么都不做并返回false。当然CAS一定要volatile变量配合,这样才能保证每次拿到的变量是主内存中最新的那个值,否则旧的预期值A对某条线程来说,永远是一个不会变的值A,只要某次CAS操作失败,永远都不可能成功。

93、线程同步需要注意什么

1、尽量缩小同步的范围,增加系统吞吐量。
2、分布式同步锁无意义,要使用分布式锁。
3、防止死锁,注意加锁顺序。

94、线程之间如何传递数据

通过在线程之间共享对象就可以了,然后通过wait/notify/notifyAll、await/signal/signalAll进行唤起和等待,比方说阻塞队列BlockingQueue就是为线程之间共享数据而设计的

95说几个常用的Lock接口实现锁

ReentrantLock、ReadWriteLock

96、什么是乐观锁和悲观锁?

乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,将比较-替换这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。
悲观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态,悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的锁,就像synchronized,不管三七二十一,直接上了锁就操作资源了

97、Hashtable的size()方法为什么要做同步?

同一时间只能有一条线程执行固定类的同步方法,但是对于类的非同步方法,可以多条线程同时访问。所以,这样就有问题了,可能线程A在执行Hashtable的put方法添加数据,线程B则可以正常调用size()方法读取Hashtable中当前元素的个数,那读取到的值可能不是最新的,可能线程A添加了完了数据,但是没有对size++,线程B就已经读取size了,那么对于线程B来说读取到的size一定是不准确的。而给size()方法加了同步之后,意味着线程B调用size()方法只有在线程A调用put方法完毕之后才可以调用,这样就保证了线程安全性
CPU执行代码,执行的不是Java代码,这点很关键,一定得记住。Java代码最终是被翻译成机器码执行的,机器码才是真正可以和硬件电路交互的代码。即使你看到Java代码只有一行,甚至你看到Java代码编译之后生成的字节码也只有一行,也不意味着对于底层来说这句语句的操作只有一个。一句"return count"假设被翻译成了三句汇编语句执行,一句汇编语句和其机器码做对应,完全可能执行完第一句,线程就切换了。

98、什么是自旋锁

自旋锁是采用让当前线程不停地的在循环体内执行实现的,当循环的条件被其他线程改变时才能进入临界区

99、什么是阻塞式方法

阻塞式方法是指程序会一直等待该方法完成期间不做其他事情,ServerSocket的accept()方法就是一直等待客户端连接。这里的阻塞是指调用结果返回之前,当前线程会被挂起,直到得到结果之后才会返回。此外,还有异步和非阻塞式方法在任务完成前就返回。

100、提交任务时线程池队列已满会时发会生什么?

当线程数小于最大线程池数maximumPoolSize时就会创建新线程来处理,而线程数大于等于最大线程池数maximumPoolSize时就会执行拒绝策略。

Last modification:October 14th, 2019 at 11:11 am
如果觉得我的文章对你有用,请随意赞赏