我们先来看一下哲学家进餐问题:
        有五个哲学家,每个哲学家手上有一只筷子,不能吃饭,拿到2只才能吃。 哲学家嘛,思考比较全面,考虑的也比较多:1.别人先给一只筷子给我,我吃完后再把筷子给其他人,让其他人也能吃上饭;2.我把筷子给别人,让别人先吃,但又担心人家吃完后不把筷子给自己。大家都这样想,每个人手上都只有一只筷子,大家都吃不成。这就造成了死锁,而这也可以说是Java线程死锁在现实生活中的体现。
        多说一句,假如我和KN手上都只有一只筷子,我肯定会把我的筷子给她,让她先吃。呵呵:)臭美一下,我想她也会这样做的。那岂不是也要造成另类的“死锁”,有办法,那我就手抓饭了,下次去超市多买双筷子,哈哈。


死锁分析:
        现在有两个线程,都能读写相同的共享数据。这样就带来了新的麻烦:由于数据共享会带来同步问题,进而会导致死锁的产生。 
        众所周知,多线程带来的好处是显而易见的,特别是性能的改善;但这个是以牺牲可靠性为代价的,主要是因为多线程共享数据有可能会产生线程死锁。举个简单的例子:第一个线程等待第二个线程释放资源,而同时第二个线程又在等待第 一个线程释放资源。双方互不相让,死锁发生,程序不能正常运行。人的现实生活又何尝不是这样,很多时候都出现对峙的状态。要是每个人都这样想就好了:只要不是涉及原则问题和自己的核心利益,退一步海阔天空。当然了,说起来容易做起来难,这是理想情况,只能往这方面努力了。
        导致死锁的根源在于不适当地运用“synchronized”同步关键词来管理线程对特定对象的访问而引起的。“synchronized”关键词的作用是,确保在某 个时刻只有一个线程被允许执行特定的同步代码块,因此,被允许执行的线程首先必须拥有对该变量或对象的排他性访问权。Java中每个对象都有一把锁与之对应。当线程访问对象时,线程会给对象加锁(监视器),而这 个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。 




以下关于上锁的知识是网上转载过来的:
上锁 
    许多线程在执行中必须考虑与其他线程之间共享数据或协调执行状态,就需要同步机制。因此大多数应用程序要求线程互相通信来同步它们的动作,在 Java 程序中最简单实现同步的方法就是上锁。在 Java 编程中,所有的对象都有锁。线程可以使用 synchronized 关键字来获得锁。在任一时刻对于给定的类的实例,方法或同步的代码块只能被一个线程执行。这是因为代码在执行之前要求获得对象的锁。 

     为了防止同时访问共享资源,线程在使用资源的前后可以给该资源上锁和开锁。给共享变量上锁就使得 Java 线程能够快速方便地通信和同步。某个线程若给一个对象上了锁,就可以知道没有其他线程能够访问该对象。即使在抢占式模型中,其他线程也不能够访问此对象, 直到上锁的线程被唤醒、完成工作并开锁。那些试图访问一个上锁对象的线程通常会进入睡眠状态,直到上锁的线程开锁。一旦锁被打开,这些睡眠进程就会被唤醒 并移到准备就绪队列中。