!!!不要认为知识过于简单,过于基础就不去看,学好任何事物都要打好基础!!!
问题:
1、什么是进程
2、什么是线程
3、CPU核心数和线程数的关系
4、cpu时间片轮询
5、上下文切换
6、并发
7、并行
8、并发编程的优缺点
9、java开启线程的方法,方法之前的区别
10、interrupt()
11、线程生命周期,join()、run()、yield()、start()
12、synchronized()、volatile()
13、ThreadLocal
14、引用、强引用、弱引用、虚引用、软引用
15、等待和通知的标准范式
答案:
1、什么是进程
进程是程序运行资源分配的最小单位,进程和进程之间是相互独立的。进程是程序在计算机上的一次执行活动。
2、什么是线程
线程是CPU调度的最小单位。必须依赖于进程而存在,线程是进程的一个实体,是CPU调度和分派的基本单位, 本身拥有程序计数器,寄存器和栈,并共享进程的资源。
3、CPU核心数和线程数的关系
多核心:多处理,依靠多个CPU同时并行地运行程序
多线程:让同一个处理器上的多个线程同步执行并共享处理器的执行资源
核心数、线程数:目前主流CPU都是多核的。增加核心数目就是为了增加线程数,因为操作系统是通过线程来执行任务的,一般情况下它们是1:1对应关系,也就是说四核CPU一般拥有四个线程。但 Intel引入超线程技术后,使核心数与线程数形成1:2的关系
4、cpu时间片轮询
时间片轮转调度是一种最古老、最简单、最公平且使用最广的算法,又称RR调度
5、上下文切换
就是一个进程切换成另一个进程
6、并发
指应用能够交替执行不同的任务。
7、并行
指应用能够同时执行不同的任务。
8、并发编程的优缺点
a) 加快响应用户的时间 b)充分利用CPU的资源 c) 可以使你的代码模块化,异步化,简单化
a)死锁 b) 安全性 c)资源耗尽形成死机当机
9、java开启线程的方法,方法之间的区别
a) extends Thread;然后X.start
b)X implements Runnable;然后交给Thread运行
Thread才是Java里对线程的唯一抽象,Runnable只是对任务(业务逻辑)的抽象。Thread可以接受任意一个Runnable的实例并执行。
10、interrupt()
interrupt() 打了个中断标志位,不代表立即停止工作,还可能不会理会。
处于死锁状态的线程无法被中断
11、线程生命周期,join()、run()、yield()、start()、
就绪状态到运行状态是为了等待cpu时间片轮转
---------》join()获取执行权
就绪====================》运行=================》死亡
《--------yield()时间片到期 --------》run()结束、stop()、setDeamon()设为守护线程
运行====================》阻塞=================》就绪
------》sleep()、wait() -------》 notify()、norifyAll()、interrupt()
start(): 让一个线程进入就绪队列等待分配cpu,分到cpu后才调用实现的run()方法,start()方法不能重复调用,如果重复调用会抛出异常
run(): 业务逻辑实现的地方
yield():使当前线程让出CPU占有权,但让出的时间是不可设定的。也不会释放锁资源。注意:并不是每个线程都需要这个锁的,而且执行yield( )的线程不一定就会持有锁,我们完全可以在释放锁后再调用yield方法
setDeamon():垃圾回收线程就是Deamon线程,finally()不一定执行
join():将两个交替执行的线程变成串行
wait():调用该方法的线程进入 WAITING状态,只有等待另外线程的通知或被中断才会返回.需要注意,调用wait()方法后,会释放对象的锁
notfiy()、notifyAll():通知一个在对象上等待的线程,使其从wait方法返回,而返回的前提是该线程获取到了对象的锁,没有获得锁的线程重新进入WAITING状态。代码块走完锁才释放。尽可能用notifyall(),谨慎使用notify(),因为notify()只会唤醒一个线程,我们无法确保被唤醒的这个线程一定就是我们需要唤醒的线程
12、synchronized()、volatile()
加锁:同步块、方法、类、对象
同步块和方法其实没什么区别;对方法加锁就是将关键字放在方法名前,对同步块加锁就是创建一个对象obj,synchronized(obj){},大括号里依旧是方法,当然不创建对象直接使用this: synchronized(this){}就是对当前对象的实例加锁也是可以的
volatile保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的,volatile不能保证数据在多个线程下同时写时的线程安全,适用于一写多读的场景
13、ThreadLocal
synchronized是利用锁的机制,使变量或代码块在某一时该仅仅能被一个线程访问。而ThreadLocal为每个线程都提供了变量的副本,使得每个线程在某一时间访问到的并非同一个对象,这样就隔离了多个线程对数据的数据共享。
14、引用、强引用、弱引用、虚引用、软引用
强引用:Object o = new Object();
软引用:垃圾回收,不一定会回收
弱引用:垃圾回收,一定会回收 WeakReference
虚引用:垃圾回收,一定会回收,会通知
15、等待和通知的标准范式
等待方遵循如下原则。
1)获取对象的锁。
2)如果条件不满足,那么调用对象的wait()方法,被通知后仍要检查条件。
3)条件满足则执行对应的逻辑。
通知方遵循如下原则。
1)获得对象的锁。
2)改变条件。
3)通知所有等待在对象上的线程。
其他小知识:
1、os限制:linux最多开1k个线程,windows最多开2k个线程
2、但 Intel引入超线程技术后,使核心数与线程数形成1:2的关系
3、废弃的方法(不是不能用,只是官方不建议用):stop()强制性过大,可能不会正常释放资源,destory(),resume()
4、jdk线程是协作式的