1、进程是包含线程的,我们经常用到的QQ、微信都属于进程,每个进程由一到多个线程组成。
2、我们所使用的主方法就是一个主线程
3、在主方法中启动其他线程,但是在启动完成后,各自就不在影响,各自执行
4、创建线程
Thread t1=new Thread(){
@verride
public void run(){
}
};
Thread t2=new Thread(){
@verride
public void run(){
}
};
t1.start();
t2.start();
5、单核CPU也可以支持多线程,多进程。
6、分时操作系统,给每个线程分配时间片,Linux的时间片是固定的,但是Windows系统时间片是不固定的。任务之间进行切换执行。
7、上下文切换,执行完时间片,切换其他进程,然后从哪里切走,再切回来。线程的切换大概达到1ms的时间。
8.主线程是当前线程,先执行,但不一定是先执行完的,而且主线程执行完之后,子线程还可以继续执行。
9、当CPU有严重浪费时,适合用多线程,多个程序同时运行是,需要用到多线程
10、java 1s发送1百万次指令,与磁盘的交互为5ms,也就是说java1ms发送1000次数据,一次数据发送需要0.001ms,那么发送一次数据就需要5.001ms,一次如果使用单线程的CPU,那么CPU就有5ms的时间是在打空转的。
实现多线程,可以成倍提高工作率,而且磁盘有多个机械臂,支持多写入。磁盘也是支持批量写入的,如果只有一个任务,那么磁盘转一圈,就会有很大一部分时间是无效写入,当有多个任务的时候,磁盘转一圈写入的效率大大增加。
11、网络爬虫抓取、数据库操作是多线程的应用场景
12、线程的性能测试工具是:Lmbench3
13、减少上下文的切换:无锁并发编程、CSA算法、使用最少线程和使用协程
实战:用jstack命令dump打印当前日志快照
sudo -u admin /opt/yfeve/java/bin/jstack 31177 > /home/tenqfei.fangtf/dump12
以管理员admin执行命令jstack 将其导入到/home/tenqfei.fangtf/dump12这个目录下
14、grep筛选指令,awk ' {print $2$3$4$5}'以什么格式输出 uniq -c统计命令
15、加锁,synchronize是给引用类型加锁,不能给基本类型上锁的。
16、每个任务CPU空闲10ms,这样的是否合适使用多线程?
不一定,要看CPU浪费的比例,如果java处理的时间3000ms才处理完毕,那么他浪费的比例并不大,所以用多线程是不合理的,来回切换线程式需要开销的。
17、java代码在编译后变成java字节码(.class),字节码被类加载器加载到jvm里,jvm执行字节码,最终需要转化为汇编指令在CPU上执行。java中所使用的并发机制依赖于jvm实现和CPU指令。
-------------------------------------------------------------------------------------------------------
18、volatile是读锁;synchronize是读写锁保证
读锁保证你读到的都是正确的,但是不保证你能修改对;读写锁保证读和写都是安全的
volatile是轻量锁,修饰的是变量;synchronize修饰的是方法,块,但不能修饰变量
19、高速缓存行:是高速缓存中的基本单位,所占的是64B,处理器在加载缓存行时会直接加载整个缓存线。此时只有一条路,别人是无法传递电信号的。
20、原子操作,要么都成功,要么都失败,意思是有十个任务,前九个都成功但是最后一个失败了,那前面九个任务就都要还原回去。
21、缓存行填充:意思是,尽可能在填充的时候把缓存行填满。读的频率比较高的适合填满缓存,这样读的速度就会快很多,因为整个缓存行就只有你一个数据,当你在读的时候就不会被缓存行的其他数据所堵塞。
22、写命中:CPU在修改数据时,要先把数据读取到缓存行,然后对缓存行的内容进行修改,在存到缓存行中,直到操作结束时才写回内存。
写命中,减少了对总线的占用,可以使其他的线程去占用总线工作,提高了工作效率。
23、写缺失(刷新缺失):在缓存行中是有一个对象的,但是在内存中,这个对象被删除了。