多线程中的互锁现象
2015-08-04 20:53
459 查看
互锁现象
在多线程中经常会出现线程间的互锁现象。进程间的互锁,假设有两个线程,线程1的完成需要用线程2 的资源,线程2的完成需要用线程1的资源。当两个线程都启动后,线程1 等待线程2 的资源, 线程2 等待线程1 的资源,以致于两个线程都没办法完成,都在等待状态。这种现象就叫做线程间的互锁。
//线程1 public class LockRunnable1 implements Runnable { private String lock1 = "lock1"; private String lock2 = "lock2"; @Override public void run() { synchronized (lock1) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("我在等你把lock2给我!"); synchronized (lock2) { } } } } //线程2 public class LockRunnable2 implements Runnable{ private String lock1 = "lock1"; private String lock2 = "lock2"; @Override public void run() { synchronized (lock2) { try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("我在等你把lock1给我!"); synchronized (lock1) { } } } } //测试 public class TestRunnable { public static void main(String[] args) { //测试互锁 LockRunnable1 run1 = new LockRunnable1(); LockRunnable2 run2 = new LockRunnable2(); Thread t1 = new Thread(run1, "小红"); Thread t2 = new Thread(run2,"小名"); t1.start(); t2.start(); } }
运行结果:
从结果中可以看到,程序一直在运行。因为红色圆圈处一直处于运行状态!
如何解决互锁
可以通过调用同步锁的wait()和notify()方法来解决互锁问题。首先说一下wait()方法,wait()方法必须用在同步锁中。调用wait()方法,线程进入等待状态,直到有notify()唤醒它。
nitify()方法同样也需要用在同步锁中。作用是将在等待状态的进程唤醒,进入运行状态。
//线程1 public class LockRunnable1 implements Runnable { private String lock1 = "lock1"; private String lock2 = "lock2"; @Override public void run() { System.out.println("run1 开始运行!"); synchronized (lock1) { //休眠1秒 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("run1释放lock1, 进入等待状态!"); try { lock1.wait();//进入等待状态。 } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("run1在等你把lock2给我!"); synchronized (lock2) { System.out.println("run1获得lock2,继续运行!"); } } } } //线程2 public class LockRunnable2 implements Runnable{ private String lock1 = "lock1"; private String lock2 = "lock2"; @Override public void run() { System.out.println("run2开始运行!"); synchronized (lock2) { //休眠1秒 try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("run2在等run1把lock1给他!"); synchronized (lock1) { System.out.println("run2获得lock1, 继续执行!"); //run2唤醒lock1 lock1.notify(); //休眠3S try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("run2 运行完毕!"); } } } } //测试 public class TestRunnable { public static void main(String[] args) { //测试互锁 LockRunnable1 run1 = new LockRunnable1(); LockRunnable2 run2 = new LockRunnable2(); Thread t1 = new Thread(run1, "小红"); Thread t2 = new Thread(run2,"小名"); t1.start(); t2.start(); } }
运行结果:
相关文章推荐
- 监听套接字 连接套接字
- [MetaHook] R_RicochetSprite
- HDU 5327 Olympiad (多校)
- Document
- c# -- 对象销毁和垃圾回收
- POJ - 1847Tram最短路
- adb无法识别魅族note2
- Contest 4 1002 Problem Killer【等差等比数列】
- linux MySQL相关问题
- errorPage跳转问题
- [LeetCode]228.Summary Ranges
- UI Overview
- 新浪微博Redis应用经验--总结自InfoQ
- Zookeeper节点类型
- java大数用法
- Tomcat开发Servlet之NoClassFoundException解决方法
- Hadoop之集群设置
- 使用原始套接字实现数据包捕获
- UVA 140
- php中的关于xml的使用(SEO)