尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

JavaEE多线程(2)

JavaEE多线程(2) 1.死锁1.1产生死锁四个必要条件只要破坏其中一条就能打破死锁1互斥条件锁是互斥的同一时间只能一个线程拿到锁。2请求与保持线程拿到一把锁又申请另一把锁并且不释放锁。3不可剥夺锁只能自己主动释放别的不可抢夺。4循环等待线程a拿到锁1申请拿锁2。线程2拿到锁2申请拿锁1。形成了循环。上述代码执行过程首先t1先拿到锁lock1并且进入睡眠不释放lock1。然后t2拿到锁lock2也进入睡眠不释放lock2。当t1苏醒后在申请拿lock2此时锁lock2已经被占用会陷入堵塞。当t2苏醒后在申请拿lock1此时锁lock1已经被占用会陷入堵塞。此时陷入循环输出结果如下程序卡住不会结束解决方法我们可以对锁进行编号任何一个线程在有多把锁的时候加锁顺序由小到大加锁此时输出可达到预期2.volatile 关键字volatile用来解决由于内存可见性引起的线程安全问题什么是内存可见性问题实例在多线程中每个线程有着自己的工作内存不是直接读写主内存存共享变量线程a修改了变量但是只改在了自己的缓存里没有同步到主内存中线程b再从主内存中读取到的数据还是原来的比如下述例子解决上述方法就是给变量加上volatile 关键字private staticvolatileboolean flag false;再加上后修改flag值会立刻把修改后的值放回到主内存中并且清空其他线程的缓存副本在读volatile变量时直接从主内存中读不会从线程自己的工作缓存中读保证了一个线程修改 volatile 变量其他线程马上能读到最新值。volatile三个作用1保证内存的可见性2禁止指令重排序CPU / JVM 为了提升运行效率在不改变单线程执行结果的前提下会打乱代码执行顺序这就叫指令重排序。3不保证原子性3.wait 和notify3.1wait方法wait会使当前执行代码的线程进入等待队并且会释放锁等待唤醒唤醒条件其他线程调⽤notify⽅法。wait(long millis)可以设置最大等待时间时间到自动唤醒不等 notify。3.2notify()⽅法notify()会随机唤醒等待队列中的线程在notify()⽅法后当前线程不会⻢上释放该对象锁要等到执⾏notify()⽅法的线程将程序执⾏ 完也就是退出同步代码块之后才会释放对象锁notifyAll()唤醒该对象等待池全部线程。3.3代码演示注意必须在synchronized(obj){ }内部调用否则直接抛异异常执行结果3.4wait 和sleep的对⽐1锁行为wait()释放锁别的线程可以拿到这把锁。sleep()抱着锁睡觉如果在同步块里 sleep其他线程拿不到锁全部阻塞。2所属类wait是Object实例对象的方法lock.wait()sleep是线程静态方法Thread.sleep(1000)3唤醒区别wait要别的线程调用 notify /notifyAll 才会被唤醒也可以被中断sleep时间到自己醒不需要别的线程通知3位置wait需要搭配synchronized使⽤.sleep不需要
返回列表