zoukankan      html  css  js  c++  java
  • Java如何使用线程解决死锁?

    在Java编程中,如何使用线程解决死锁?

    以下示例演示如何使用线程的概念解决死锁问题。

    // from W w w .Y I I b  AI.c  o  M
    package com.yiibai;
    
    import java.util.*;
    import java.util.concurrent.*;
    import java.util.concurrent.locks.*;
    
    public class SolvingDeadlock extends ReentrantLock {
        private static List deadlockLocksRegistry = new ArrayList();
    
        private static synchronized void registerLock(SolvingDeadlock ddl) {
            if (!deadlockLocksRegistry.contains(ddl))
                deadlockLocksRegistry.add(ddl);
        }
    
        private static synchronized void unregisterLock(SolvingDeadlock ddl) {
            if (deadlockLocksRegistry.contains(ddl))
                deadlockLocksRegistry.remove(ddl);
        }
    
        private List hardwaitingThreads = new ArrayList();
    
        private static synchronized void markAsHardwait(List l, Thread t) {
            if (!l.contains(t))
                l.add(t);
        }
    
        private static synchronized void freeIfHardwait(List l, Thread t) {
            if (l.contains(t))
                l.remove(t);
        }
    
        private static Iterator getAllLocksOwned(Thread t) {
            SolvingDeadlock current;
            ArrayList results = new ArrayList();
            Iterator itr = deadlockLocksRegistry.iterator();
    
            while (itr.hasNext()) {
                current = (SolvingDeadlock) itr.next();
                if (current.getOwner() == t)
                    results.add(current);
            }
            return results.iterator();
        }
    
        private static Iterator getAllThreadsHardwaiting(SolvingDeadlock l) {
            return l.hardwaitingThreads.iterator();
        }
    
        private static synchronized boolean canThreadWaitOnLock(Thread t, SolvingDeadlock l) {
    
            Iterator locksOwned = getAllLocksOwned(t);
            while (locksOwned.hasNext()) {
                SolvingDeadlock current = (SolvingDeadlock) locksOwned.next();
                if (current == l)
                    return false;
                Iterator waitingThreads = getAllThreadsHardwaiting(current);
    
                while (waitingThreads.hasNext()) {
                    Thread otherthread = (Thread) waitingThreads.next();
                    if (!canThreadWaitOnLock(otherthread, l)) {
                        return false;
                    }
                }
            }
            return true;
        }
    
        public SolvingDeadlock() {
          this(false, false);
       }
    
        public SolvingDeadlock(boolean fair) {
          this(fair, false);
       }
    
        private boolean debugging;
    
        public SolvingDeadlock(boolean fair, boolean debug) {
          super(fair);
          debugging = debug;
          registerLock(this);
       }
    
        public void lock() {
            if (isHeldByCurrentThread()) {
                if (debugging)
                    System.out.println("Already Own Lock");
                super.lock();
                freeIfHardwait(hardwaitingThreads, Thread.currentThread());
                return;
            }
            markAsHardwait(hardwaitingThreads, Thread.currentThread());
            if (canThreadWaitOnLock(Thread.currentThread(), this)) {
                if (debugging)
                    System.out.println("Waiting For Lock");
                super.lock();
                freeIfHardwait(hardwaitingThreads, Thread.currentThread());
    
                if (debugging)
                    System.out.println("Got New Lock");
            } else {
                throw new DeadlockDetectedException("DEADLOCK");
            }
        }
    
        public void lockInterruptibly() throws InterruptedException {
            lock();
        }
    
        public class DeadlockDetectingCondition implements Condition {
            Condition embedded;
    
            protected DeadlockDetectingCondition(ReentrantLock lock, Condition embedded) {
                this.embedded = embedded;
            }
    
            public void await() throws InterruptedException {
                try {
                    markAsHardwait(hardwaitingThreads, Thread.currentThread());
                    embedded.await();
                } finally {
                    freeIfHardwait(hardwaitingThreads, Thread.currentThread());
                }
            }
    
            public void awaitUninterruptibly() {
                markAsHardwait(hardwaitingThreads, Thread.currentThread());
                embedded.awaitUninterruptibly();
                freeIfHardwait(hardwaitingThreads, Thread.currentThread());
            }
    
            public long awaitNanos(long nanosTimeout) throws InterruptedException {
                try {
                    markAsHardwait(hardwaitingThreads, Thread.currentThread());
                    return embedded.awaitNanos(nanosTimeout);
                } finally {
                    freeIfHardwait(hardwaitingThreads, Thread.currentThread());
                }
            }
    
            public boolean await(long time, TimeUnit unit) throws InterruptedException {
                try {
                    markAsHardwait(hardwaitingThreads, Thread.currentThread());
                    return embedded.await(time, unit);
                } finally {
                    freeIfHardwait(hardwaitingThreads, Thread.currentThread());
                }
            }
    
            public boolean awaitUntil(Date deadline) throws InterruptedException {
                try {
                    markAsHardwait(hardwaitingThreads, Thread.currentThread());
                    return embedded.awaitUntil(deadline);
                } finally {
                    freeIfHardwait(hardwaitingThreads, Thread.currentThread());
                }
            }
    
            public void signal() {
                embedded.signal();
            }
    
            public void signalAll() {
                embedded.signalAll();
            }
        }
    
        public Condition newCondition() {
            return new DeadlockDetectingCondition(this, super.newCondition());
        }
    
        private static Lock a = new SolvingDeadlock(false, true);
        private static Lock b = new SolvingDeadlock(false, true);
        private static Lock c = new SolvingDeadlock(false, true);
    
        private static Condition wa = a.newCondition();
        private static Condition wb = b.newCondition();
        private static Condition wc = c.newCondition();
    
        private static void delaySeconds(int seconds) {
            try {
                Thread.sleep(seconds * 1000);
            } catch (InterruptedException ex) {
            }
        }
    
        private static void awaitSeconds(Condition c, int seconds) {
            try {
                c.await(seconds, TimeUnit.SECONDS);
            } catch (InterruptedException ex) {
            }
        }
    
        private static void testOne() {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("thread one grab a");
                    a.lock();
                    delaySeconds(2);
                    System.out.println("thread one grab b");
                    b.lock();
                    delaySeconds(2);
                    a.unlock();
                    b.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("thread two grab b");
                    b.lock();
                    delaySeconds(2);
                    System.out.println("thread two grab a");
                    a.lock();
                    delaySeconds(2);
                    a.unlock();
                    b.unlock();
                }
            }).start();
        }
    
        private static void testTwo() {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("thread one grab a");
                    a.lock();
                    delaySeconds(2);
                    System.out.println("thread one grab b");
                    b.lock();
                    delaySeconds(10);
                    a.unlock();
                    b.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("thread two grab b");
                    b.lock();
                    delaySeconds(2);
                    System.out.println("thread two grab c");
                    c.lock();
                    delaySeconds(10);
                    b.unlock();
                    c.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("thread three grab c");
                    c.lock();
                    delaySeconds(4);
                    System.out.println("thread three grab a");
                    a.lock();
                    delaySeconds(10);
                    c.unlock();
                    a.unlock();
                }
            }).start();
        }
    
        private static void testThree() {
            new Thread(new Runnable() {
                public void run() {
                    System.out.println("thread one grab b");
                    b.lock();
                    System.out.println("thread one grab a");
                    a.lock();
                    delaySeconds(2);
                    System.out.println("thread one waits on b");
                    awaitSeconds(wb, 10);
                    a.unlock();
                    b.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                public void run() {
                    delaySeconds(1);
                    System.out.println("thread two grab b");
                    b.lock();
                    System.out.println("thread two grab a");
                    a.lock();
                    delaySeconds(10);
                    b.unlock();
                    c.unlock();
                }
            }).start();
        }
    
        public static void main(String args[]) {
            int test = 1;
            if (args.length > 0)
                test = Integer.parseInt(args[0]);
            switch (test) {
            case 1:
                testOne();
                break;
            case 2:
                testTwo();
                break;
            case 3:
                testThree();
                break;
            default:
                System.err.println("usage: java DeadlockDetectingLock [ test# ]");
            }
            delaySeconds(60);
            System.out.println("--- End Program ---");
            System.exit(0);
        }
    }
    
    class DeadlockDetectedException extends RuntimeException {
        public DeadlockDetectedException(String s) {
            super(s);
        }
    }
    
    Java

    上述代码示例将产生以下结果 -

    thread one grab a
    Waiting For Lock
    thread two grab b
    Got New Lock
    Waiting For Lock
    Got New Lock
    thread one grab b
    Exception in thread "Thread-1" thread two grab a
    Waiting For Lock
    com.yiibai.DeadlockDetectedException: DEADLOCK
        at com.yiibai.SolvingDeadlock.lock(SolvingDeadlock.java:102)
        at com.yiibai.SolvingDeadlock$2.run(SolvingDeadlock.java:213)
        at java.lang.Thread.run(Unknown Source)
  • 相关阅读:
    jquery 锚点跳转、滚动导航菜单和返回顶部
    jQuery attr方法-获得修改元素属性值
    layui中的tab选项卡,循环多个选项卡后不出现折叠的解决方法
    获取地址url的参数值
    vant的tab选项卡的点击事件传参
    css选择器
    jquery实现换一批内容
    letter-spacing 字体间距
    jquery 隔行变色
    Redis与Memcached的区别
  • 原文地址:https://www.cnblogs.com/borter/p/9613434.html
Copyright © 2011-2022 走看看