取百家之长,仅用作个人的学习之用,侵删。
1进程、线程、协程 2 并行和并发 3锁 4 Linux常用命令
进程、线程、协程
区别和联系 进程是系统资源分配的最小单位,线程是程序执行的最小单位。 进程是一个实体。每一个进程都有它自己的地址空间,而线程共享进程的地址间。
一个进程可以拥有多个线程一样,一个线程也可以拥有多个协程。
协程
协程不是被操作系统内核所管理,而完全是由程序所控制(也就是在用户态执行)。协程暂停,和线程的阻塞是有本质区别的。协程的暂停完全由程序控制,线程的阻塞状态是由操作系统内核来进行切换。
因此,协程的开销远远小于线程的开销。
同步与异步:任务是否在一个线程中执行
阻塞与非阻塞:异步执行任务时,线程是否会阻塞等待结果,还是继续执行
线程调度
按照特定机制为多个线程分配CPU的使用权。调度算法:先来先服 务调度、优先级调度、多级反馈队列调度、高响应比优先调度。
进程切换分两步:
1.切换页目录以使用新的地址空间
2.切换内核栈和硬件上下文
线程切换步骤 CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态(程序计数器),以便下次切换回这个任务时,可以再次加载这个任务的状态,从任务保存到再加载的过程就是一次上下文切换。
对于linux来说,线程和进程的最大区别就在于地址空间,对于线程切换,第1步是不需要做的,第2是进程和线程切换都要做的。
切换的性能消耗:
线程上下文切换的代价 上下文切换会导致额外的开销,因此减少上下文切换次数便可以提高多线程程序的运行效率。减少上下文切换的方法有无锁并发编程、CAS算法、使用最少线程和使用协程。
1、线程上下文切换和进程上下问切换一个最主要的区别是线程的切换虚拟内存空间依然是相同的,但是进程切换是不同的。这两种上下文切换的处理都是通过操作系统内核来完成的。内核的这种切换过程伴随的最显著的性能损耗是将寄存器中的内容切换出。
2、上下文的切换会扰乱处理器的缓存机制。简单的说,一旦去切换上下文,处理器中所有已经缓存的内存地址一瞬间都作废了。还有一个显著的区别是当你改变虚拟内存空间的时候,处理的页表缓冲全部刷新,这将导致内存的访问在一段时间内相当的低效。但是在线程的切换中,不会出现这个问题。
继承Thread类,实现Runable接口。重写run方法,start运行。Thread类中的join方法的主要作用就是同步,它可以使得线程之间的并行执行变为串行执行。
并行和并发
并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其它线程处于挂起状。.这种方式我们称之为并发(Concurrent)。
并行:当系统有一个以上CPU时,则线程的操作有可能非并发。当一个CPU执行一个线程时,另一个CPU可以执行另一个线程,两个线程互不抢占CPU资源,可以同时进行,这种方式我们称之为并行(Parallel)。
区别:并发和并行是即相似又有区别的两个概念,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。在多道程序环境下,并发性是指在一段时间内宏观上有多个程序在同时运行,但在单处理机系统中,每一时刻却仅能有一道程序执行,故微观上这些程序只能是分时地交替执行。倘若在计算机系统中有多个处理机,则这些可以并发执行的程序便可被分配到多个处理机上,实现并行执行,即利用每个处理机来处理一个可并发执行的程序,这样,多个程序便可以同时执行。
ReentrantLock与 Synchronized
点击查看详细文章:
Synchronized进过编译,会在同步块的前后分别形成monitorenter和monitorexit这个两个字节码指令。在执行monitorenter指令时,首先要尝试获取对象锁。如果这个对象没被锁定,或者当前线程已经拥有了那个对象锁,把锁的计算器加1,相应的,在执行monitorexit指令时会将锁计算器就减1,当计算器为0时,锁就被释放了。如果获取对象锁失败,那当前线程就要阻塞,直到对象锁被另一个线程释放为止。
ReentrantLock的高级功能,主要有以下3项:
1.等待可中断,持有锁的线程长期不释放的时候,正在等待的线程可以选择放弃等待,这相当于Synchronized来说可以避免出现死锁的情况。通过lock.lockInterruptibly()来实现这个机制。
2.公平锁,多个线程等待同一个锁时,必须按照申请锁的时间顺序获得锁,Synchronized锁非公平锁,ReentrantLock默认的构造函数是创建的非公平锁,可以通过参数true设为公平锁,但公平锁表现的性能不是很好。
3.锁绑定多个条件,一个ReentrantLock对象可以同时绑定对个对象。ReenTrantLock提供了一个Condition(条件)类,用来实现分组唤醒需要唤醒的线程们,而不是像synchronized要么随机唤醒一个线程要么唤醒全部线程。
死锁
指由于两个或者多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,无法前往执行。
//静态对象是类的所有对象共享的 private static Object o1 = new Object(), o2 = new Object();
synchronized (o1) { Thread.sleep(500); synchronized (o2) { System.out.println("1..........");} }
synchronized (o2) {Thread.sleep(500); synchronized (o1) {System.out.println("2.........."); } }
wait和sleep的区别
1.wait是Object的方法,sleep是Thread的方法
2.wait需要用于同步代码块中来释放锁,sleep不会释放锁,且可在任何地方使用
3.sleep需要捕获异常
乐观锁和悲观锁
(1)乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,将比较-设置这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。
(2)悲观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态,悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,都会持有一个独占的锁,就像synchronized,不管三七二十一,直接上了锁就操作资源了。
ThreadLocal
的实例代表了一个线程局部的变量,每条线程都只能看到自己的值,并不会意识到其它的线程中也存在该变量。
它采用采用空间来换取时间的方式,解决多线程中相同变量的访问冲突问题。
ThreadLocal的实现原理
Callable与Runnable Thread
LInux常用命令
awk AWK是一种处理文本文件的语言 # 每行按空格或TAB分割,输出文本中的1、4项 $ awk '{print $1,$4}' log.txt
top top命令经常用来监控Linux的系统状况 top –hv | -abcHimMsS –d delay –n iterations –p pid [, pid …]
netstat 查看端口被占用情况 netstat -an | grep 3306
grep 文本搜索工具 查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串"update"的文 件,并打印出该字符串所在行的内容,使用的命令为: grep -r update /etc/acpi
more vs cat more命令和cat的功能一样都是查看文件里的内容,但有所不同的是more可以按页来查看文件的内容,还支持直接跳转行等功能。 more +3 test.log #从第三行开始显示日志内容
less less 与 more 类似,但使用 less 可以随意浏览文件,而 more 仅能向前移动,却不能向后移动,而且 less 在查看之前不会加载整个文件。 浏览多个文件 lesstest2.log test.log
tail tail命令用途是依照要求将指定的文件的最后部分输出到标准设备,通常是终端。tail -r -n 10 filename 说明:逆序显示filename最后10行