并发一(基本概念及理论准备)
目录一、线程与进程二、线程实现三、线程生命周期及状态转换四、常见操作方法分析五、线程池六、常见并发容器七、线程安全一、线程与进程进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,是系统进行资源分配和调度的一个独立单位,是程序运行的最小单元线程是指进程中的一个执行流程,没有自己的内存空间,是cpu运行和分派的最小单元。在Java中,每次程序运行至少启动2个线程:一个是main线程
写在前面:
多线程并发等知识点涉及面广,延伸度大,理论加源码的方式整理关于线程的部分基础知识,其他更多的更深的知识会在后面一一学习和整理,先学习基础,再延伸。
目录
一、线程与进程
进程是指一个内存中运行的应用程序,每个进程都有自己独立的一块内存空间,是系统进行资源分配和调度的一个独立单位,是程序运行的最小单元。
线程是指进程中的一个执行流程,没有自己的内存空间,是cpu运行和分派的最小单元。
在Java中,每次程序运行至少启动2个线程:一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM实际上就是在操作系统中启动了一个进程。
二、线程实现
继承 Thread
由于java是单继承,所以基本不用这种实现方式
实现Runnable
接口,重写run()
实现Callable&Future
待续
三、线程生命周期及状态转换
新建
new 【来到体育场 】
可运行
runnable 【进入备跑区】
线程对象创建后,其他线程调用了该线程的start方法,进入线程池等待被调度选中,获取cpu使用权。当前线程sleep()方法结束,其他线程join()结束,等待用户输入完毕,某个线程拿到对象锁,这些线程也将进入可运行状态。当前线程时间片用完了,调用当前线程的yield()方法,当前线程进入可运行状态。锁池里的线程拿到对象锁后,进入可运行状态。
运行
running 【起跑】
runnable状态下获得了cpu时间片(timeslice),执行程序。
阻塞
blocked 【停下去做点啥】
线程因为某些原因放弃了cpu使用权,让出了cpu timeslice,暂停运行。直到线程重新进入runnable。
所谓阻塞状态是正在运行的线程没有运行结束,暂时让出CPU,这时其他处于就绪状态的线程就可以获得CPU时间,进入运行状态。
blocked分三种:
等待阻塞 wait()方法执行,进入等待队列(waitting queue)
同步阻塞 running的线程在获取对象的同步锁时,若该同步锁被别的线程占用,JVM会把它放到锁池(lock pool)中,等拿到锁之后才会进入可运行
其他阻塞 Thread.sleep(long ms) 睡上五分钟,醒来再进线程池
t.join() 跑着跑着突然被插队,你不得不停下
发出IO请求时,jvm会把该线程置为阻塞状态。 跑着跑着,你去看了看文件,所以得停下
当 sleep()状态超时 睡醒了
join()等待线程终止或者超时 插队的人走了或挂了
或者I/O处理完毕时 文件看完了
线程重新转入可运行(runnable)状态。
等待
waiting 【等着,别人叫再跑】
处于这种状态的线程不会被分配CPU执行时间,它们要等待被显式地唤醒,否则会处于无限期等待的状态。
超时等待
time waiting 【等着,过了等待时间就不等了】
处于这种状态的线程不会被分配CPU执行时间,不过无须无限期等待被其他线程显示地唤醒,在达到一定时间后它们会自动唤醒。
终止
terminated 【跑完或者意外退场】
run()、main()执行结束,或因异常退出run()方法,结束该线程生命周期,死亡的不可复生。
四、常见操作方法分析
Thread.sleep(long millis)
一定是当前线程调用此方法,当前线程进入阻塞,但不释放对象锁,millis后线程自动苏醒进入可运行状态。作用:给其它线程执行机会的最佳方式。
Thread.yield()
一定是当前线程调用此方法,当前线程放弃获取的cpu时间片,由运行状态变会可运行状态,让OS再次选择线程。作用:让相同优先级的线程轮流执行,但并不保证一定会轮流执行。实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。Thread.yield()不会导致阻塞。
t.join()/t.join(long millis)
当前线程里调用其它线程1的join方法,当前线程阻塞,但不释放对象锁,直到线程1执行完毕或者millis时间到,当前线程进入可运行状态。
obj.wait()
当前线程调用对象的wait()方法,当前线程释放对象锁,进入等待队列。依靠notify()/notifyAll()唤醒或者wait(long timeout)timeout时间到自动唤醒。
obj.notify()
唤醒在此对象监视器上等待的单个线程,选择是任意性的。notifyAll()唤醒在此对象监视器上等待的所有线程。
五、线程池
ThreadPoolExecutor extends Executor
六、常见并发容器
ConcurrentHashMap
待续
其他并发容器
待续
队列
同步队列
当前线程想调用对象A的同步方法时,发现对象A的锁被别的线程占有,此时当前线程进入同步队列。简言之,同步队列里面放的都是想争夺对象锁的线程。同步队列是在同步的环境下才有的概念,一个对象对应一个同步队列。
锁池队列
锁池里面放的都是想争夺对象锁的线程。当一个线程1被另外一个线程2唤醒时,1线程进入锁池状态,去争夺对象锁。
锁池是在同步的环境下才有的概念,一个对象对应一个锁池。
等待队列
待续
七、线程安全
定义:CPU的使用权抢占和资源的共享发生了冲突
更多推荐
所有评论(0)