Java多线程编程(一)-死锁

  死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程。

  首先我们来看下面一段死锁代码

 1 package com.company;
 2 
 3 import static java.lang.Thread.sleep;
 4 
 5 public class Main{
 6     private static Integer a = new Integer(0);
 7     private static Integer b = new Integer(0);
 8 
 9     public static void main(String...args) {
10         Thread thread1 = new Thread(new Runnable() {
11             @Override
12             public void run() {
13                 synchronized (a) {
14                     try {
15                         System.out.println("thread1 get a");
16                         sleep(1000);   // 为防止该线程同时获得a和b两个对象的锁
17                         synchronized (b) {
18                             System.out.println("thread1 get a and b");
19                         }
20                     } catch (InterruptedException e) {
21                         e.printStackTrace();
22                     }
23                 }
24             }
25         });
26 
27         Thread thread2 = new Thread(new Runnable() {
28             @Override
29             public void run() {
30                 synchronized (b) {
31                     System.out.println("thread2 get b");
32                     synchronized (a) {
33                         System.out.println("thread2 get a and b");
34                     }
35                 }
36             }
37         });
38         thread1.start();
39         thread2.start();
40     }
41 }
// output:

thread1 get a
thread2 get b

上面代码运行将会产生死锁,因为thread1在获取a的锁后会尝试获取b的锁,但是因为此时thread2保持着b的锁且thread1保持着thread2所需要的a,因此两个线程陷入僵持状态,产生死锁.

  1. 解决死锁的办法:
    1. 避免一个线程同时获取多个锁。
    2. 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
    3. 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
    4. 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。
posted @ 2018-02-08 00:23  zq216991  阅读(422)  评论(0编辑  收藏  举报