多线程安全问题
当多个线程共同访问一个对象时,造成数据不一致!效果图示:
原因总结:
-
-
临界资源:共享资源(同一对象),一次仅允许一个线程使用,才可保证其正确性。
-
由于验证代码if(money<balance) 和 balance -= money 这两个是一个整体(原子操作),而多线程会破坏这种原子操作导致了安全问题!
解决方案
同步代码块
synchronized(临界资源对象){ //对临界资源对象加锁 //代码(原子操作) } 注: "每个对象都有一个互斥锁标记,用来分配给线程的。“ "只有拥有对象互斥锁标记的线程,才能进入对该对象加锁的同步代码块。" "线程退出同步代码块时,会释放相应的互斥锁标记。"
同步方法
synchronized 返回值类型 方法名称(形参列表){ //对当前对象(this)加锁 //代码(原子操作) } 注: "只有拥有对象互斥锁标记的线程,才能进入对该对象加锁的同步代码块。" "线程退出同步代码块时,会释放相应的互斥锁标记。"
死锁
-
当第一个线程拥有A对象锁标记,并等待B对象锁标记,同时第二个线程拥有B对象锁标记,并等待A对象锁标记时,产生死锁。
-
演示案例: 一绑匪绑了张三的女友,给张三打电话要求张三先交钱,再放其女友;张三说只有先放人再给钱。用程序模拟:
创建执行绑匪任务的线程,手握两把锁
创建执行男友任务的线程,也是手握俩两把锁,顺序相反!
双方互相持有对方所需的锁标记而不相让,这样僵持的状态称之为死锁
通过死锁和生产者消费者两个问题发现,在引入了锁机制后带来了一些问题,因此设想如果线程之间能通信该多好啊!
线程通讯
要解决以上的问题,必须要在线程间通信。
notify All()通知唤醒因obj对象而无限等待的线程