-
什么是线程?线程和进程的区别?
线程是进程的一个执行单元,是比进程还要小的独立运行的基本单位。
根本区别:进程是资源分配最小单位,线程是程序执行的最小单位。
地址空间:进程有自己独立的地址空间,线程没有独立的地址空间
资源拥有:进程之间的资源是独立的;同一进程内的线程共享本进程的资源
-
描述CPU和多线程的关系
单CPU多任务阶段,计算机在同一时间点,并行执行多个线程。但这并非真正意义上的同时执行,而是多个任务共享一个CPU,操作系统协调CPU在某个时间点,执行某个线程,因为CPU在线程之间切换比较快,给人的感觉,就好像多个任务在同时运行
多CPU多任务阶段,真正实现的,在同一时间点运行多个线程
-
什么是线程安全/线程不安全?
线程安全:
指多个线程在执行同一段代码的时候采用加锁机制,使每次的执行结果和单线程执行的结果都是一样的,不存在执行程序时出现意外结果。
线程不安全:
是指不提供加锁机制保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据。
-
描述下线程的生命周期?(画图)
-
wait、sleep、join、yield的区别
wait,释放cpu资源,也释放锁资源
sleep ,释放cpu资源,不释放锁资源
join:一种特殊的wait,当前运行线程调用另一个线程的join方法,当前线程进入阻塞状态直到另一个线程运行结束等待该线程终止
yield:让出CPU调度,只能让同优先级或更高的线程有执行的机会
-
Synchronized和Lock的区别
1、synchronized锁是可以帮助我们自动开锁和关闭锁 2、Lock锁,我们最常用的是ReentrantLock重入锁,需要我们手动的开锁和手动关锁 3、synchronized只能与wait()、notify()方法一起使用 4、ReentrantLock只能与Condition类中的await()、single()方法一起使用
-
ThreadLocal、Volatile、Synchronized 的作用和区别
1.volatile
volatile主要是用来在多线程中同步变量,当一个变量被volatile修饰后,该变量就不能被缓存到线程的内存中,该变量有变化时,所有调用该变量的线程都会获得相同的值
2.ThreadLocal
ThreadLocal是一个线程的局部变量,会为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本
3.synchronized
当在对象上调用其任意的synchronized方法时,此对象被加锁(一个任务可以多次获得对象的锁,计数会递增),同时在线程从该方法返回之前,该对象内其他所有要调用类中被标记为synchronized的方法的线程都会被阻塞
-
同步方法和同步块,哪个更好?
同步块是更好的选择,因为它不会锁住整个对象(当然你也可以让它锁住整个对
象)。同步方法会锁住整个对象,哪怕这个类中有多个不相关联的同步块,这通
常会导致他们停止执行并需要等待获得这个对象上的锁。
同步块更要符合开放调用的原则,只在需要锁住的代码块锁住相应的对象,这样
从侧面来说也可以避免死锁。
-
什么是死锁?如何避免死锁?
使用同步的多个线程同时持有对方运行时所需要的资源
尽量不要出现锁的嵌套
避免多次锁定
使用定时锁
死锁检测
-
常见的线程池叫什么,线程池的作用是什么
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
1、重用线程池的线程,可以避免因为线程的创建和销毁锁带来的性能开销
2、可以有效的控制线程池的最大并发数,避免量的线程之间因为抢占系统资源而阻塞
3、可以对线程进行简单的管理,除此之外,还可以提供以下的特定操作,例:
提供定时、定期、单线程、并发数控制等功能
操作系统 为进程分配资源、对进程进行调度管理。 1个进程内包含多个线程。 线程是进程的一部分。 CPU用于调度线程
线程安全是多线程编程时的计算机程序代码中的一个概念。在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
JAVA内存模型
每条指令都是在CPU中执行的。 在执行指中,数据的读取和写入进行完成。 int i=1; 主内存(物理内存) i=i+1; //i++; 高速缓存: CPU的指令执行速度比在主内存中操作的要快的多。 当程序在运行过程中,会将运算需要的数据从主存(物理内存)复制一份到CPU的高速缓存中。CPU进行计算时就可以直接从它的高速缓存进行数据的读取和写入。 当运算结束之后,再将高速缓存中数据刷新到主内存当中。
JAVA并发编程
1、原子性(即一个操作或多个操作,要么全部执行,要么全部不执行)。 int i=10; i=i+1; // i++; //i=10; 答:可通过synchroinzed和lock实现。(能够保证任一时刻只有一个线程执行代码块,解决了原子性问题)。 2、可见性 多个线程访问同一个变量时,一个线程修改了这个变量的值,其余线程能够立刻得到修改的值。 答:可通过synchroinzed和lock实现。(能够保证任一时刻只有一个线程执行代码块,解决了原子性问题、并且在释放锁之前会将变量的修改刷新到主内存中,--》可见性)。 Volatile:当一个共享变量被volatile修饰,它会保证修改的值会立刻被更新到主内存中。当有其它线程需要读取时,会去主内存中读取新值。 3、有序性 程序执行的代码按顺序(先后)执行。 (处理器为了提高程序运行速度,可能会对输入代码进行优化,不会保证程序中的各个语句的执行顺序(先后)同代码中的顺序一致。但是它会保证程序最终的执行结果和代码顺序执行的结果是一致的。 int i=1000; boolean falg=true;