Java死锁的理解
我们有时候操作数据库的时候会遇到死锁,那么什么使死锁呢?它的一个比较官方的定义就是:死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。我们也可以通过下面一个小故事来进行简单的理解。就是说吧有两个人他们在一起吃饭,但是呢,筷子不够,A这个人有一支筷子,B这个人也有一支筷子,加入A要吃饭的时候,B把筷子给了A,这样A就吃上了饭,同理B要吃饭的时候,A把筷子给了B,这样B也吃上了饭,如果要是这样的话,就没有我们什么事了,但是有一天,有一道菜非常好吃,A、B都想先吃,A向B拿筷子,B也先向A拿筷子。两人都不愿意把筷子给对方,那只能一直耗着,等着,那么我们就可以说他们两个死锁了。
那么如何使用java来编写一个死锁程序呢。简单来说就是在同步代码块中嵌套同步代码块,两个同步代码块应用了两个不同的锁。A线程的第一个同步代码块用到了锁A,第二个同步代码块用到了锁B。B线程第一个同步代码块用到了锁B,第二个同步代码块用到了锁A。这样当A线程运行的时候先用了锁A,还没有用到锁B的时候,B线程也启动了,用到了锁B,这时A线程要用锁B,然而这时B线程却已经占用了锁B,而B线程继续运行需要锁A,可是A线程已经占用了锁B,这样话,这两个线程就出现了死锁。示例代码如下:
package com.day05; /** * 死锁:就是同步代码块中嵌套另外一个同步代码块 * * @author Administrator * */ public class DeadLockDemo { public static void main(String[] args) { // 创建两个线程 DeadLockThread dt1 = new DeadLockThread(false); DeadLockThread dt2 = new DeadLockThread(true); // 启动线程 new Thread(dt1).start(); new Thread(dt2).start(); } } class DeadLockThread implements Runnable { // 标记变量 private boolean flag; public DeadLockThread(boolean flag) { super(); this.flag = flag; } public void run() { // dt1线程执行该方法 if (flag) { synchronized (ThreadLock.locka) { System.out.println("if locka!"); synchronized (ThreadLock.lockb) { System.out.println("if lockb!"); } } } // dt2线程执行该方法 else { synchronized (ThreadLock.lockb) { System.out.println("else lockb!"); synchronized (ThreadLock.locka) { System.out.println("else locka!"); } } } } } class ThreadLock { static Object locka = new Object(); static Object lockb = new Object(); }
运行结果:
if locka!
else lockb!
这个时候程序就卡着不动了,也就死锁了。希望大家可以通过此示例了解死锁,应尽量在程序中避免死锁.