java 并发 (一)
创建线程两种方式
java线程特征
- priority:优先级,取值1-10,值越大优先级越高
- deamon:是否守护线程,可以通过setDeamon/isDeamon设置获取
- name:名字
- id:thread对象的标识
- 所有java程序,都有一个名为mian的主线程
- java线程共享所有资源
java线程状态
可以通过Thread.getState()方法获取对应的状态
- NEW:Thread对象已经创建,但是还没有开始执行。
- RUNNABLE:Thread对象正在Java虚拟机中运行。
- BLOCKED : Thread对象正在等待锁定。
- WAITING:Thread 对象正在等待另一个线程的动作。
- TIME_WAITING:Thread对象正在等待另一个线程的操作,但是有时间限制。
- TERMINATED:Thread对象已经完成了执行。
中断
- isinterrupted(),是否被中断。
synchronized使用
- 给实例方法加synchronized关键字——获取实例对象上的锁
- 给静态方法加synchronized关键字——获取Class对象上的锁
- synchronized(对象){}
synchronized本质
- 利用监视器对线程进行排队、阻塞、激活(管程MESA单条件队列)
- threadId,用于记录持有锁对象的线程
- waitQueue(waitSet),等待队列
- entryQueue(entryList),阻塞队列
wait/notify
什么情况下会抛出Interrupted异常
只有那些声明了会抛出InterruptedException的函数才会抛出异常,也就是下面这些常用的函数
- Java.lang.Object 类的wait 方法
- java.lang.Thread 类的sleep 方法
- java.lang.Thread 类的join 方法
线程关闭
- stop/destory
- 设置关闭标志位
Thread类怎么处理异常
- 可以在Thread中设置异常处理类(实例方法)--setUncaughtExceptionHandler
- 构造函数传一个ThreadGroup(在ThreadGroup定义处理异常的方法)
Thread.interupt()方法可以打断哪些线程?
- 轻量级阻塞(即Waiting、Time_Waiting)都可以被打断
- 执行了Thread.sleep()的线程,这个线程可能还没睡够,可以终止他的睡眠
- 状态变化
- 执行Thread.sleep()前——Runnable
- 执行了Thread.sleep()后——Time_Waiting
- 执行了interrupt()后——RUNNABLE
- 状态变化
- 执行了Object.wait()且锁没有被占据的线程,这个线程可以被打断,触发InterruptedException
- 状态变化
- Object.wait()前——Runnable
- Object.wait()后——waiting/time_waiting
- 执行了interrupt()后——Blocked
- 执行了interrupt()后+拿到锁——RUNNABLE
- 注意:Time_Waiting/Waiting状态的线程不一定能被interrupt()方法打断,如果是因为wait()方法导致的等待状态,其实还会进入Blocked状态
- 状态变化
- 执行了Thread.join()的线程,这个跟sleep()方法类似
并发和并行的区别
- 并发是指同一时间能处理两个或者多个事情
- 并发是指在一个时间段能处理两个或者多个事情
同步两种方式、并发编程两大问题
- 同步:线程之间如何通信、协作,也就是常说的控制同步,线程/进程协同完成一组任务
- 互斥:数据访问同步,即同一时刻只允许一个线程访问共享资源,是指对临界资源的访问,同一时刻只能有一个线程/进程访问
同步两种机制
- 信号量
- Monitor 监视器/管程
- Monitor 直译过来就是 "监视器",操作系统领域一般都翻译成 "管程"。
- 所谓管程,指的是管理共享变量以及对共享变量的操作过程,让他们支持并发。
- 在Java中,就是管理类的成员变量和成员方法,让这个类是线程安全的。
- 现在主要用的都是MESA模型,synchronized用的是只有一个条件队列的MESA模型,Lock支持多条件队列
- 想了解管程/MESA模型,可以看看MESA模型结构分析 JDK 为什么选择管程,还有就是操作系统的书籍了
不可变对象
原子操作和原子变量
线程/进程通信:
- 共享内存
- 消息传递