1.进程与线程的区别?
答:进程是所有线程的集合,每一个线程是进程的一条执行路径。
2.为什么要用多线程?
答:提高程序效率
3.创建线程的方式?那种方式比较好?
答:1.继承Thread类创建线程
2.实现Runnable接口创建线程
3.使用Callable和Future创建线程。有返回值,可以声明抛出异常。
实现Runnable的方式比较好,可以继承别的类。继承Thread类不能再继承别的类。多实现单继承。
4.什么是线程安全?
答:当多个线程对同一个共享变量发起写操作,可能会发的生数据冲突问题,也就是线程安全问题。
5.线程安全的解决方案?
答:synchronized关键字修饰代码块或方法、Lock锁。
6.synchronized和Lock的区别?
答:1.synchronized是关键字Lock是接口。
2.synchronized是自动释放锁,lock需要手动释放(unlock())。
3.Lock可以让等待的线程相应中断,synchronized会一直等待。
4.通过Lock可以直接拿到锁,synchronized不行。
5.Lock能提高多个线程读的效率
6.synchronized能作用在类、方法、代码块上,Lock只能作用在方法内。
7.什么是死锁?
答:当两个及两个以上线程互相持有对方所需要的资源,无法继续执行,导致死锁。
例子:两个人A和B被锁在不同的房间里,A的钥匙在B身上,B的钥匙在A身上,自己出不去都不会把钥匙给对方。这样就导致了死锁。
8.死锁产生的必要条件
答:1.互斥条件
2.请求和保持条件
3.不剥夺条件
4.环路等待条件。
9.如何避免死锁?
答:1.加锁的顺序。
2.设置锁的超时时间。
3. 破坏死锁产生的四个必要条件之一。
4.死锁检测及解除 。通过系统检测机构及时的检测出死锁的发生,然后采取某种策略解除死锁
10.什么是ThreadLocal?
答:ThreadLocal:线程局部变量。key-value键值对方式存储。key为当前线程,value为存储的数据。
ThreadLocal主要有四个方法:
Object get():返回当前线程对应的线程局部变量的值
void set():设置当前线程的局部变量的值
void remove():将当前线程局部变量的值删除,目的是减少内存的使用,当线程结束后,对应线程的局部变量将会自动回收,显式调用时为了加快内存回收的速度。
initialValue():返回该线程局部变量的初始值。这个方法是延迟调用方法,在线程第一次调用get或者set方法时才执行,并且只执行一次。
11.多线程的三大特性?
答:原子性、可见性、有序性。
原子性:即一个操作或者多个操作,要么全部执行并且执行过程中会被打断,要么全不执行。
可见性:当多个线程访问同一个变量,一个线程修改了该变量的值,其他线程能够立马看到。
有序性:程序执行的顺序按照代码先后顺序执行。
12.java的内存模型?
答:共享内存模型指的就是java内存模型(又名JMM),JMM决定一个线程对共享变量的写入时,对另外的线程可见。
主要分为主内存和本地私有内存,线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。
13.Volatile关键字?
答:Volatile保证了线程间共享变量的及时可见性,但不能保证原子性。
可见性是指,当某个线程修改了volatile修饰的变量,它会保证修改的值会立即被更新到主存。
Volatile特性:
1.保证此变量对所有的线程的可见性,即保证新修改的值能立即同步到主内存中,以及每次使用前立即从主内存刷新。
2.禁止指令重排序:有volatile修饰的变量,赋值后多执行了一个“load addl $0x0, (%esp)”操作,这个操作相当于一个内存屏障(指令重排序时不能把后面的指令重排序到内存屏障之前的位置),只有一个CPU访问内存时,并不需要内存屏障;(什么是指令重排序:是指CPU采用了允许将多条指令不按程序规定的顺序分开发送给各相应电路单元处理)。
volatile性能:
volatile 的读性能消耗与普通变量几乎相同,但是写操作稍慢,因为它需要在本地代码中插入许多内存屏障指令来保证处理器不发生乱序执行。
14.volatile和synchronized区别?
答:1.volatile能够保证可见性,但无法保证原子性。
2.synchronized关键字是防止多个线程同时执行同一段代码,会影响程序的执行效率,而volatile关键字在某些情况下性能是要优于synchronized关键字的。
注意:volatile无法替代synchronized关键字,因为volatile关键字无法保证操作的原子性。
15.Lock和synchronized关键字的区别?
答:1.Lock是一个接口synchronized是一个关键字。
2.Lock需要手动释放锁(手动锁),synchronized自动释放(自动锁)。
3.Lock是公平锁,synchronized是非公平锁。
4.synchronized无法获得所得状态,发生异常会自动释放锁。
5.synchronized不可中断 持有锁线程一直不释放,其他只能阻塞等待 lock可以设置时间进行放弃等待
16.什么是线程通讯?
答:多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。
其实就是多个线程在操作同一个资源,但是操作的动作不同。
17.多线程间如何进行通讯?
答:使用wait、notify方法。
wait:暂停当前正在执行的线程,并释放资源,让其他线程可以有机会运行。
notify/notifyall:唤醒正在暂停的线程。
注意:一定是在synchronized内使用,并且是同一个锁的资源。
18.wait和sleep的区别?
答:1.sleep方法属于Thread类,wait方法属于Object类。
2.sleep方法使了程序暂停执行指定的时间,让出cpu,但是他的监控状态依然保持,当指定时间到了恢复运行。
在调用sleep方法过程中,线程不会释放对象锁。而调用wait方法时,线程会放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象调用notify()方法后本线程才进入对象锁定池准备获取对象锁,进入运行状态。