1、线程和进程的区别
- 本质区别: 进程是一个程序的实例,是操作系统资源分配的最小单位;,是任务调度与执行的最小单位
- 包含关系: 进程至少由一个线程组成,线程可看做轻量级进程
- 资源开销: 进程有自己的资源可以单独执行,进程之间的切换会有较大的开销;线程不独有资源,共享着进程的资源,每个线程有自己的栈和程序计数器,线程切换开销小。
- 健壮影响: 线程崩溃后一般不影响其他进程,线程崩溃后可能导致整个进程终止。
- 进程之间有父子关系;线程没有,但是有main方法作为主线程
- 因为线程之间存在共享资源的问题,可能存在对同一临界资源的争夺,存在同步和互斥关系。
2、什么是守护线程
守护线程
和用户线程
用户线程就是正常意义上的线程,我们执行程序时默认的都是用户线程。
守护线程是指在程序运行的后台提供的通用线程,顾名思义,守护线程就是用户线程的守护者,基本构造和用户线程是一样的,除了一点:
当 jvm 关闭后守护进程才关闭。也就是说只要还存在用户线程时,守护线程就一定在。
例如:将一个线程设置为守护线程的方法就是在调用start()启动线程之前调用对象的setDaemon(true)方法。
守护线程的一个典型的例子就是垃圾回收器。只要JVM启动,它始终在运行,实时监控和管理系统中可以被回收的资源
@Slf4j
public class ThreadTest {public static void main(String[] args) {log.info("main Start ...");Thread myThread1 = new MyThread1();myThread1.setName("测试线程");myThread1.setDaemon(true);myThread1.start();log.info("main End ...");}
}@Slf4j
class MyThread1 extends Thread{@Overridepublic void run() {log.info(Thread.currentThread().getName()+" begin....");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}log.info(Thread.currentThread().getName()+" end.....");}
}
3、并行和并发的区别
一个客观前提:一个CPU在某一时刻只能处理一个任务
并行:指在多核处理器下,每个cpu处理一个线程任务,形成了某一时刻物理上的多个线程同时进行
并发:指一个cpu快速切换处理多个线程任务,形成了用户状态上的多个线程同时进行,某一时刻物理上一个cpu仍旧只能处理一个线程。
4、CPU核数与并发数有关联吗?
物理上1 个cpu 某一时刻只能处理 1个线程,4核CPU最多可以同时跑4个线程(不考虑超线程),超线程技术简单理解为这个技术可以把1个CPU当成2个CPU用。
5、创建线程的几种方式 总结描述
- 继承 Thread 重写 run 方法;
- 实现 Runnable 接口,重写run 方法;
- 实现 Callable 接口 + Future 创建有返回值的线程。
- 线程池创建线程
6、线程池的了解 线程池学习
7、Java 中如何保证线程安全
- 使用线程安全的类。例如
package java.util.concurrent;
- 使用自动锁 synchronized synchronized 学习了解
- 自定义锁
8、Java 如何避免死锁问题
死锁的造成原因的必要条件是线程获取锁顺序不当
- 使用线程安全的类。例如
package java.util.concurrent;
- 避免使用多个锁,减少嵌套锁的使用
- 合理分配资源的使用顺序
- 使用定时锁,使用死锁检测工具
9、synchronized 和 volatile 的区别
- volatile 只能修饰变量;synchronized 可以修饰变量、方法、代码块、类
- volatile 原理是内存可见,每次访问变量时都从主存刷数据;synchronized 则是获取对象头的锁状态,进行加锁和解锁
- volatile 支持内存可见,不支持原子性(除了基本类型的简单操作,例如 ++ 或者 --),synchronized 支持内存可见,也通过锁支持了原子性
- volatile 不会造成线程阻塞问题,但是 synchronized 因为加锁可能造成线程阻塞问题