并发编程-线程基础

进程和线程的区别
学习线程之前,首先要知道什么是进程。简单的理解,一个应用程序就是一个进程,比如开启一个QQ,微信,腾讯视频。线程可以说是进程的执行单元,一条执行路径。线程被包含在进程中,一个进程至少有一个线程,但可以有多个线程。

为什么用多线程
为什么需要多线程呢?试想一下你的生活,厨房一般都有两个煤气灶,你可以使用第一个灶烧水的同时,用第二个灶蒸馒头,这样就大大节省了时间,或者说在你洗脚的时候吃饭?例子不太恰当,但就是这个意思。

时间片轮转机制
在最开始,多线程并不是真正意义上的同时执行,因为只有一个cpu,cpu只是在做着特别特别特别快的切换,在同一时刻,只能运行一个线程,切换的频率是非常快的,随机的,让你觉得他是在同时执行,但线程特别多的时候就会卡顿。到后来,多核cpu出现,这时候才是真正的多个线程同时执行。

多线程一定好嘛
合理的运用多线程可以提高效率,比如常见的迅雷(同时下载任务),360(一边清理磁盘垃圾一边杀毒)。但cpu核数不够支撑太多线程的时候,就会出现卡顿,严重会宕机,使用多线程时,还要考虑死锁以及线程安全等问题。

线程的生命周期
image.png
关于这个生命周期,说几种的都有,不同的书里说什么词的也都有,不过大概意思都是一样的
1.新建:也就是new了一个线程,重写了run(),还没有调用start()方法
2.就绪:调用了start()方法,线程进入就绪状态,因为即使调用了start()方法开启了线程,但在这个时刻,也未必拿到cpu的执行权,但已经具备了执行资格
3.运行:得到了cpu的执行权
4.阻塞:调用了sleep方法或者wait方法,此时线程不具备执行资格和执行权,notify后,线程会重新进入就绪状态,等待获取cpu的执行权
5.死亡:方法自然执行结束或调用了结束线程的方法

创建线程
继承Thread类
实现Runnable接口
实现Callable接口

结束线程
stop() 过时,强制干掉,resume() 过时 suspend() 过时,抢占资源
interrupt(),中断线程,只是一个标记位,将线程标记置为true,并不强制干掉线程。需要子线程去判断标记协作处理
isInterrupt(),判断线程的标记
interrupted(),静态方法,将线程标记置为false

线程扩展方法
run()和start()区别,run方法和正常调用没区别,都是new对象,然后调用方法,start方法才是真正开启线程,而run方法是只是执行的任务
yield()方法,交出执行权,进入执行资格队列
setPriority(int i)方法,设置线程优先级,默认5,设置1-10,不代表一定会执行哪个多哪个少
setDeamon(boolean b)守护线程,跟着主线程混,主线程执行完,子线程就结束。注意:子线程里面的finally块不一定会被执行
join() 加入线程,线程A里面执行了线程B.join(),那么A就需要等待线程B执行完成

synchronized关键字
保证原子性和可见性(线程安全),注意对象锁和类锁的使用,静态方法默认就是类锁。

volatile关键字
相当于在内存中共享变量,最轻量级的同步机制,保证变量在内存中的可见性。但是不保证原子性,适合一写多读的情况

ThreadLocal
各线程之间不共享变量,用当前线程做键,值随意。提供get set方法,不用手动remove,垃圾回收机制会自动回收。适合每个线程池持有自己的链接情况下使用

notify()和notifyAll()
notify调用后,会唤醒等待池中的其中一个线程
notifyAll会唤醒等待池中的所有线程

yield(),sleep(),wait(),notify()对锁的影响
yield执行后,不释放锁
sleep也不释放锁
wait调用必须先持有锁,调用后锁被释放
notify调用必须先持有锁,调用notify本身并不会释放锁,而是代码块执行完之后释放锁

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章