进程:是一个正在执行中的程序,
每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。
线程:是进程中的一个独立的控制单元,
线程在控制中进程的执行。
提高效率,各自相互运行!(各线程运行的机会是平等的)
一个进程中至少有一个线程。
运行状态:cup只能执行一个线程(不断的切换线程,没有运行的,就处于临时状态,等待运行——————各线程运行的机会是平等的)
临时(阻塞)状态:具备运算资格,但是没有执行权(临时状态过了以后就到了 运行状态start())
冻结状态:放弃了执行资格
(睡眠状态sleep(time)时间到了后就到了到了 临时状态 或者 等待状态wait(),notify()等待被唤醒到了 临时状态)
消亡状态:stop()或者 run方法结束。线程也就执行完了
多线程的安全问题!!!
问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没有执行完,
另一个线程参与进来执行,导致共享数据的错误。
解决方法:
对多条操作共享数据的语句时,只能让一个线程都执行完,在执行过程中,其他线程不可以参与运行
java对于多线程的安全问题提供了专业的解决方式:就是同步代码块
(同步的前提:
1>必须要有两个或者两个以上的线程
2>必须是多个线程使用同一个锁
)
同步里面必须保证:只有一个线程在运行
利与弊:解决了多线程安全问题,变得有序了!但是多个线程必须判断锁(也就是监听器判断是否有人),较为消耗的资源
(同步代码块)synchronized(对象)
{
需要同步的代码
}
(同步方法)public synchronized void 方法名(){
需要同步的代码
}
run(){
this.方法名(需要同步的方法名)
}
同步举例:火车的卫生间问题。
1.目的:该程序是否有安全问题,如果有,如何解决?
如何找安全问题:
1>明确哪些代码是多线程运行代码。
2>明确共享数据。
3>明确多线程运行代码中那些语句是操作共享数据的。
2.同步函数用的是哪一个锁呢?
函数需要被对象调用,那么函数都有一个所属对象引用,就是this.
所以同步函数使用的锁就是this(对象一定要一样)
3.如果同步函数被被静态方法修饰后,使用的锁是什么呢?
通过验证,发现不在是this,因为静态方法中也不刻意定义this.
那么是谁?
静态方法进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件对象。
类名.class 该对象的类型是Class.
静态的同步方法,使用的锁是该方法所在类的字节码文件对象。 类名.class
对于多个生产者和消费者
为什么要定义while判断标记
原因:让被唤醒的线程再一次判断标记。
为什么要定义notify.
因为需要唤醒对象线程
因为只用notify,容易出现只唤醒本方的线程的情况,导致程序中的所有线程都等待。
***********重点
JDK1.5中提供多线程升级解决方案(现实锁机制,锁的操作机制)
将同步Synchronized替换成现实Lock操作
将Object中wait,notify,notifyAll,替换了Condition对象
将对象可以Lock锁 进行获取
该实例中,实现了本方只唤醒对方的操作!
**********