1、线程和进程的区别是什么
进程:进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动。它是操作系统动态执行的基本单元,在传统的操作系统中,进程既是基本的分配单元,也是基本的执行单元。
线程:通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义。线程可以利用进程所拥有的资源,在引入线程的操作系统中,通常都是把进程作为分配资源的基本单位,而把线程作为独立运行和独立调度的基本单位,由于线程比进程更小,基本上不拥有系统资源,故对它的调度所付出的开销就会小得多,能更高效的提高系统多个程序间并发执行的程度。
生活实例:使用QQ,查看进程一定有一个QQ.exe的进程,我可以用qq和A文字聊天,和B视频聊天,给C传文件,给D发一段语音。
2、Java默认有几个线程
默认有2 个线程,分别是 mian和GC
3、Java 真的可以开启线程吗
不能,实际还是JVM底层调用操作系统的线程
4、并发与并⾏的区别
并发:同一时刻多个线程在访问同一个资源,多个线程对一个点
例子:小米9今天上午10点,限量抢购
春运抢票
电商秒杀...
并行:多项工作一起执行,之后再汇总
例子:泡方便面,电水壶烧水,一边撕调料倒入桶中
5、java获取cpu核心线程数
// 获取cpu核心线程数
// CPU 密集型,IO密集型
System.out.println(Runtime.getRuntime().availableProcessors()); // 12
6、线程有几个状态
public enum State {
/** 新生 */
NEW,
/** 运行 */
RUNNABLE,
/** 阻塞 */
BLOCKED,
/** 等待 */
WAITING,
/** 超时等待 */
TIMED_WAITING,
/** 终止 */
TERMINATED;
}
7、BLOCKED(阻塞),WAITING(等待),TIMED_WAITING(超时等待)的区别
BLOCKED(阻塞)
Java文档官方定义BLOCKED状态是:“这种状态是指一个阻塞线程在等待monitor(对象监视器)锁。”
真实生活例子:今天你要去面试。这是你梦想的工作,你已经盯着它多年了。你早上起来,准备好,穿上你最好的外衣,对着镜子打理好。当你走进车库发现你的老婆已经把车开走了。在这个场景,你只有一辆车,要怎么办?在真实生活中,可能会打架。 现在因为你老婆把车开走了你被BLOCKED了。你不能去参加面试。
这就是BLOCKED状态。用技术术语讲,你是线程T1,你老婆是线程T2,而锁是车。T1被BLOCKED在锁(例子里的车)上,因为T2已经获取了这个锁。
小贴士:当线程调用Object#wait()方法进入一个synchronized块/方法或重进入一个synchronized锁/方法时会等待获取monitor锁。
WAITING(等待)
Java文档官方定义WAITING状态是:“一个线程在等待另一个线程执行一个动作时在这个状态”
真实生活例子:再看下几分钟后你的老婆开车回家了。现在你意识到快到面试时间了,而开车过去很远。所以你拼命地踩油门。限速120KM/H而你以160KM/H的速度在开。很不幸,一个交警发现你超速了,让你停到路边。现在你进入了WAITING状态。你听下车坐在那等着交警过来检查你并放行。基本上,只有等他让你走。而这时你被卡在WAITING状态了。
用技术术语来讲,你是线程T1而交警是线程T2。你释放你的锁(例子中你停下了车),并进入WAITING状态,直到警察(例子中T2)让你走,你陷入了WAITING状态。
小贴士:当线程调用以下方法时会进入WAITING状态:
Object#wait() 而且不加超时参数
Thread#join() 而且不加超时参数
LockSupport#park()
在对象上的线程调用了Object.wait()会进入WAITING状态,直到另一个线程在这个对象上调用了Object.notify()或Object.notifyAll()方法才能恢复。一个调用了Thread.join()的线程会进入WAITING状态直到一个特定的线程来结束。
TIMED_WAITING(超时等待)
Java文档官方定义TIMED_WAITING状态为:“一个线程在一个特定的等待时间内等待另一个线程完成一个动作会在这个状态”
真实生活例子:尽管充满戏剧性,你在面试中做的非常好,惊艳了所有人并获得了高薪工作。(祝贺你!)你回家告诉你的邻居你的新工作并表达你激动的心情。你的朋友告诉你他也在同一个办公楼里工作。他建议你坐他的车去上班。你想这不错。所以第一天,你走到他的房子。在他的房子前停好你的车。你等了10分钟,但你的邻居没有出现。你继续开自己的车去上班,这样你不会在第一天就迟到。这就是TIMED_WAITING.
用技术术语来解释,你是线程T1而你的邻居是线程T2。你释放了锁(这里是停止开车)并等了足足10分钟。如果你的邻居T2没有来,你继续开车。
小贴士:调用了以下方法的线程会进入TIMED_WAITING:
Thread#sleep()
Object#wait() 并加了超时参数
Thread#join() 并加了超时参数
LockSupport#parkNanos()
LockSupport#parkUntil()
8、 sleep()和wait()的区别
wait:放开手里的锁去睡,会释放锁
sleep:抱着锁去睡,醒了手里还有锁,不会释放锁
wait是Object的方法,sleep是thread的方法
9、什么是可重入锁
- 可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁,直白的理解就是可以重复获取相同的锁
- synchronized和ReentrantLock都是可重入的
10、并发下集合类不安全怎么解决(java.util.ConcurrentModificationException 并发修改异常)
List
List<String> list1 = new Vector<>(); List<String> list2 = Collections.synchronizedList(new ArrayList<>()); List<String> list3 = new CopyOnWriteArrayList<>();
Set
Set<String> set1 = Collections.synchronizedSet(new HashSet<>()); Set<String> set2 = Collections.synchronizedSet(new HashSet<>());